九补丁内容区域不起作用

Nine-patch content area not working

我正在尝试将 TextView 的框架制作成云。但是内容区域的行为并不像预期的那样。我做错了什么?

您可以使用 this tool 创建您的九补丁图像。

我有一个建议无法正常工作,因为内容区域较少缩放区域。好难过。我重新制作它以手动处理 9-p​​atch。不带.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);
}
});

您为右边框和底边框设置了良好的值。您只需为左边框和上边框设置相同的值,左边框 = 右边框和上边框 = 下边框。

draw9patch中的结果:

这里是 9 补丁文件:

请注意,您的图片不太适合使用 9-patch 格式。

我extended/adapted @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();

}

我使用来自 ->

的 SizeAwareImageView 而不是 TextView

在我的例子中是这样的->

 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);
            }

        }
    }