2015-04-15 1 views
3

Я пытаюсь создать рамку для TextView как облака. Но область содержимого не ведет себя так, как ожидалось. Что я делаю не так? enter image description hereОбласть содержимого Nine-patch не работает

nine-patch not working

enter image description here

+1

Пожалуйста, делитесь девять патч изображения – LaurentY

+0

Здесь вы идете. Загружено. – ahtartam

+0

Я считаю, что этот ответ объясняет проблему довольно хорошо: [Android-контент с девятью патчами не соблюден] (http://stackoverflow.com/a/20962766/383414). Подумайте с точки зрения «заполнения» вокруг области содержимого, вместо того, чтобы думать о реальном содержании. –

ответ

1

У меня есть предложение, которое работает неправильно, потому что область содержимого меньше области масштабирования. Так грустно. Я переделал его, чтобы обрабатывать 9-патч вручную. Сохраняйте фотографии без .9.png. Получите битмап. Есть 9-строчный подарок. С помощью getPixels вычитается отступы и устанавливаем его в TextView. После этого вычисляем и устанавливаем LayoutParams.width и LayoutParams.height. Выглядит немного уродливо, но работает довольно быстро, и, самое главное, правильно.

private int startX=-1; 
 
private int endX=-1; 
 
private int contentW=-1; 
 
private int contentH=-1; 
 

 
Bitmap bmp=BitmapFactory.decodeResource(getResources(), mIconResId); 
 
int[] pixels=new int[bmp.getWidth()*bmp.getHeight()]; 
 
bmp.getPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(),bmp.getHeight()); 
 
for(int i=0;i<bmp.getWidth();i++){ 
 
    if(startX==-1 && pixels[bmp.getWidth()*(bmp.getHeight()-1)+i]==Color.BLACK){ 
 
    startX=i; 
 
    } 
 
    if(startX!=-1 && pixels[bmp.getWidth()*(bmp.getHeight()-1)+i]!=Color.BLACK){ 
 
    endX=i; 
 
    break; 
 
    } 
 
} 
 
int startY=-1; 
 
int endY=-1; 
 
for(int i=0;i<bmp.getHeight();i++){ 
 
    if(startY==-1 && pixels[bmp.getWidth()*(i+1)-1]==Color.BLACK){ 
 
    startY=i; 
 
    } 
 
    if(startY!=-1 && pixels[bmp.getWidth()*(i+1)-1]!=Color.BLACK){ 
 
    endY=i; 
 
    break; 
 
    } 
 
} 
 

 
setBackground(new BitmapDrawable(getResources(),Bitmap.createBitmap(bmp, 1, 1, bmp.getWidth()-2, bmp.getHeight()-2))); 
 

 
contentW=endX-startX; 
 
endX=bmp.getWidth()-endX; 
 
contentH=endY-startY; 
 
endY=bmp.getHeight()-endY; 
 

 
new Handler().post(new Rannable(){ 
 
@Override 
 
public void run() { 
 
    int w=textview.getWidth(); 
 
    int h=textview.getHeight(); 
 

 
    if(w>endX-startX){ 
 
    float k=((float)w)/contentW; 
 
    startX=(int) (startX*k); 
 
    endX=(int) (endX*k); 
 
    } 
 
    if(h>endY-startY){ 
 
    float k=((float)h)/contentH; 
 
    startY=(int) (startY*k); 
 
    endY=(int) (endY*k); 
 
    } 
 

 
    w+=startX+startX; 
 
    h+=startY+endY; 
 
    textview.setPadding(startX, startY, endX, endY); 
 
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(w,h); 
 
    textview.setLayoutParams(lp); 
 
} 
 
});

+0

По-прежнему требуется правильное решение, а не обходное решение. – ahtartam

+0

Но это обходное решение отлично работает. – ahtartam

-1

Вы можете использовать this tool для создания ваших девять-коммутационные изображений.

+0

Этот инструмент дает тот же результат. – ahtartam

0

Вы установили хорошие значения для правой и нижней границ. Вам просто нужно установить одинаковые значения для левой и верхней границ, левая граница = правая граница и верхняя граница = нижняя граница.

Результат в draw9patch: enter image description here

А вот файл 9-патч:

enter image description here

Для вашей информации, изображение не очень подходит для использования с форматом 9-патч.

+0

@ahtartam, полезно ли это? – LaurentY

+1

Нет, мне нужно искаженное изображение. Равномерно по всей ширине. И одинаково масштаб на всех высотах. – ahtartam

+0

Итак, вы не должны использовать 9-патч, вам нужно масштабировать полное изображение (9-патч-масштаб часть изображения) и путем вычисления размера текста. – LaurentY

0

Я продлил/адаптировал код @ahtartam. Я не уверен, что это самый чистый способ, но он работает для меня. Если кому-то нужна помощь, просто свяжитесь со мной или спросите в комментариях!

public void setTextLayout(int orgW, int orgH,int actW,int actH,int top,int left) { 

    int startX = -1; 
    int endX = -1; 
    int startY = -1; 
    int endY = -1; 
    int contentW; 
    int contentH; 

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.image); 
    int[] pixels = new int[orgW * orgH]; 
    bmp.getPixels(pixels, 0, orgW, 0, 0, orgW, orgH); 
    for (int i = 0; i < orgW; i++) { 
     if (startX == -1 && pixels[orgW * (orgH - 1) + i] == Color.BLACK) { 
      startX = i; 
     } 
     if (startX != -1 && pixels[orgW * (orgH - 1) + i] != Color.BLACK) { 
      endX = i; 
      break; 
     } 
    } 

    for (int i = 0; i < orgH; i++) { 
     if (startY == -1 && pixels[orgW * (i + 1) - 1] == Color.BLACK) { 
      startY = i; 
     } 
     if (startY != -1 && pixels[orgW * (i + 1) - 1] != Color.BLACK) { 
      endY = i; 
      break; 
     } 
    } 


    m_marvin.setImageDrawable(new BitmapDrawable(getResources(), Bitmap.createBitmap(bmp, 1, 1, orgW - 2, orgH - 2))); 
    RelativeLayout.LayoutParams rp = (RelativeLayout.LayoutParams) m_marvin.getLayoutParams(); 


    contentW=endX- startX; 
    contentH=endY-startY; 

    endX=orgW-endX; 
    endY=orgH-endY; 



    double scaleX = ((double)actW)/bmp.getWidth(); 
    double scaleY = ((double)actH)/bmp.getHeight(); 

    startX = (int) (startX * scaleX); 
    endX = (int) (endX * scaleX); 

    startY = (int) (startY * scaleY); 
    endY = (int) (endY * scaleY) ; 

    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int)(contentW*scaleX),(int)(contentH*scaleY)); 
    layoutParams.setMargins(startX+rp.leftMargin+left, startY+rp.topMargin+top, endX+rp.rightMargin, endY+rp.bottomMargin); 

    layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL,RelativeLayout.TRUE); 
    m_text.setLayoutParams(layoutParams); 
    m_text.bringToFront(); 

} 

Вместо TextView я использую SizeAwareImageView из ->https://stackoverflow.com/a/15538856/1438596

В моем случае это выглядит как this->

public class SizeAwareImageView extends ImageView { 
     MainActivity m_mainActivity; 

     public SizeAwareImageView(Context context,AttributeSet attrss){ 
      super(context,attrss); 
      m_mainActivity = (MainActivity)context; 
     } 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

      if(m_mainActivity.getTextMeasured())return; 
      // Get image matrix values and place them in an array 
      float[] f = new float[9]; 
      getImageMatrix().getValues(f); 

      // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY) 
      final float scaleX = f[Matrix.MSCALE_X]; 
      final float scaleY = f[Matrix.MSCALE_Y]; 

      // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight) 
      final Drawable d = getDrawable(); 
      final int origW = d.getIntrinsicWidth(); 
      final int origH = d.getIntrinsicHeight(); 

      // Calculate the actual dimensions 
      final int actW = Math.round(origW * scaleX); 
      final int actH = Math.round(origH * scaleY); 

      int top = (int) (imgViewH - actH)/2; 
      int left = (int) (imgViewW - actW)/2; 

      if(origW!=actW){ 
       m_mainActivity.setTextMeasured(true); 
      m_mainActivity.setTextLayout(origW, origH, actW, actH,top,left); 
      } 

     } 
    }