自定义控件动态加载textview轻松实现换行

来源:互联网 发布:小米手机怎么数据恢复 编辑:程序博客网 时间:2024/05/22 06:46

 

自定义父类控件

public class CheyouquanLinearLayout extends ViewGroup {
  int mLeft, mRight, mTop, mBottom;
     @SuppressWarnings("rawtypes")
  Hashtable map = new Hashtable();
     public CheyouquanLinearLayout(Context context) {
         super(context);
     }

     public CheyouquanLinearLayout(Context context, int horizontalSpacing, int verticalSpacing) {
         super(context);
     }

     public CheyouquanLinearLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
     }

     @SuppressLint("DrawAllocation")
  @SuppressWarnings("unchecked")
  @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int mWidth = MeasureSpec.getSize(widthMeasureSpec);
         int mCount = getChildCount();
         int mX = 0;
         int mY = 0;
         mLeft = 0;
         mRight = 0;
         mTop = 0;
         mBottom = 0;
         int j = 0;
         @SuppressWarnings("unused")
   View lastview = null;
         for (int i = 0; i < mCount; i++) {
             final TextView child = (TextView) getChildAt(i);
             String ss=child.getText().toString();
           
             child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
             // 此处增加onlayout中的换行判断,用于计算所需的高度
             int childw = child.getMeasuredWidth();
             int childh = child.getMeasuredHeight();
             mX += childw;  //将每次子控件宽度进行统计叠加,如果大于设定的高度则需要换行,高度即Top坐标也需重新设置


             Position position = new Position();
             mLeft = getPosition(i - j, i);
             mRight = mLeft + childw;
             if (mX >= mWidth) {
                 mX = childw;
                 mY += childh;
                 j = i;
                 mLeft = 0;
                 mRight = mLeft + child.getMeasuredWidth();
     mTop = mY;
     //PS:如果发现高度还是有问题就得自己再细调了
             }
             mBottom = mTop + child.getMeasuredHeight();
             mY = mTop;  //每次的高度必须记录 否则控件会叠加到一起
             position.left = mLeft;
             position.top = mTop;
             position.right = mRight;
             position.bottom = mBottom;
             map.put(child, position);
         }
         setMeasuredDimension(mWidth, mBottom);
     }


     @Override
     protected LayoutParams generateDefaultLayoutParams() {
         return new LayoutParams(1, 1); // default of 1px spacing
     }


     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         int count = getChildCount();
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
             Position pos = (Position) map.get(child);
             if (pos != null) {
                 child.layout(pos.left, pos.top, pos.right, pos.bottom);
             } else {
                 Log.i("MyLayout", "error");
             }
         }
     }


     private class Position {
         int left, top, right, bottom;
     }


     public int getPosition(int IndexInRow, int childIndex) {
         if (IndexInRow > 0) {
             return getPosition(IndexInRow - 1, childIndex - 1)
                     + getChildAt(childIndex - 1).getMeasuredWidth();
         }
         return getPaddingLeft();
     }

 

实现一行显示不完,显示下一行,依次类推

holder.tv.removeAllViews();
  String[] str=new String[4];
  String content=entity.getContent().trim();
  String name=entity.getName().trim();
  final String userid=entity.getUserid().trim();
  final String targetid=entity.getTargetid().trim();
  str[0]=name;
  str[3]=" "+content;
  if(TextUtils.isEmpty(entity.getTargetid())||entity.getTargetid().equals("0")){
   str[1]="";
   str[2]="";
  }else{
   str[1]=" 回复 ";
   String targetName=entity.getTargetname();
   str[2]=targetName;
  }
  //获取屏幕宽度
  DisplayMetrics metric = new DisplayMetrics(); 
  context.getWindowManager().getDefaultDisplay().getMetrics(metric);
     //dp转化成px
  float scale = context.getResources().getDisplayMetrics().density;
  int widthQi=(int) (90*scale + 0.5f);
  int widthQuan = metric.widthPixels-widthQi; //获取评论的总宽度
  float widthQ=0;
  //遍历评论和被评论名及评论的内容 动态生成TextView
  for (int a = 0; a <str.length; a++) {
   String na=str[a];
   if(TextUtils.isEmpty(na)){
    continue;
   }
   /***************以下为换行操作start**********************/
   //获取数据宽度
      TextView tvName=new TextView(context);
      tvName.setText(na);
      tvName.setTextSize(14);
   int wgName = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
      int hgName = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
      tvName.measure(wgName, hgName);
      //获取字符串的长度
   int widthName=tvName.getMeasuredWidth();//px
   //获取前面的本行的所有宽度
   float widthD=widthQ;
   widthQ=widthName+widthQ;
   //判断是否换行
   if(widthQ<=widthQuan){
    TextView tv=new TextView(context);
    tv.setText(na);
    tv.setTextSize(14);
    if(a==0||a==2){
     tv.setTextColor(Color.rgb(20, 150, 193));
    }else{
     tv.setTextColor(Color.BLACK);
    }
    holder.tv.addView(tv);
    if(a==0){//评论人的id
     tv.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
       Intent intent = new Intent(context, MyActivity.class);
       intent.putExtra("id",id);
       context.startActivity(intent);
      }
     });
    }else if(a==2){//被回复人的id
     tv.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
       Intent intent = new Intent(context, MyActivity.class);
       intent.putExtra("id",tid);
       context.startActivity(intent);
      }
     });
    }else if(a==3){
     tv.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
      }
     });
    }
   }else{
    float widths=widthQuan-widthD;
    String b="";
    int wss=0;
    for(int h=0;h<na.length();h++){
     b=b+na.charAt(h);
     TextView tvName2=new TextView(context);
     tvName2.setText(b);
     tvName2.setTextSize(14);
     int wName2 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        int hName2 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        tvName2.measure(wName2,hName2);
        //获取字符串的长度
     int wsName2=tvName2.getMeasuredWidth();//px
     if(wsName2>widths){
      wss=h-1;
      break;
     }else if(wsName2==widths){
      wss=h;
      break;
     }
    }
    /**一个textview拆成两个textview*/
    String name1=na.substring(0, wss+1);
    String name2=na.substring(wss+1,na.length());
    if(!TextUtils.isEmpty(name1)){
     TextView tv=new TextView(context);
     tv.setText(name1);
     tv.setTextSize(14);
     if(a==0||a==2){
      tv.setTextColor(Color.rgb(20, 150, 193));
     }else{
      tv.setTextColor(Color.BLACK);
     }
     holder.tv.addView(tv);
     if(a==0){//评论人的id
      tv.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        Intent intent = new Intent(context, MyPhotoActivity.class);
        intent.putExtra("friends_id",userid);
        context.startActivity(intent);
       }
      });
     }else if(a==2){//被回复人的id
      tv.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        Intent intent = new Intent(context, MyActivity.class);
        intent.putExtra("friends_id",targetid);
        context.startActivity(intent);
       }
      });
     }else if(a==3){
      tv.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
      
       }
      });
     }
     
    }
    if(!TextUtils.isEmpty(name2)){
     TextView tv=new TextView(context);
     tv.setText(name2);
     tv.setTextSize(14);
     if(a==0||a==2){
      tv.setTextColor(Color.rgb(20, 150, 193));
     }else{
      tv.setTextColor(Color.BLACK);
     }
        tv.measure(wgName, hgName);
        //获取字符串的长度
     int widthTv=tv.getMeasuredWidth();//px
     int countName2=widthTv/widthQuan;//判断下面还有多少整行
    
     if(countName2==0){
      holder.tv.addView(tv);
     }else{
      //遍历行数
      for(int c=0;c<countName2;c++){
       String d="";
       for(int h=0;h<name2.length();h++){
        d=d+name2.charAt(h);
        TextView tvName2=new TextView(context);
        tvName2.setText(d);
        tvName2.setTextSize(14);
        int wName2 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
           int hName2 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
           tvName2.measure(wName2,hName2);
           //获取字符串的长度
        int wsName2=tvName2.getMeasuredWidth();//px
        if(wsName2>widthQuan){
         wss=h-1;
         break;
        }else if(wsName2==widthQuan){
         wss=h;
         break;
        }
       }
       String name3=name2.substring(0, wss+1);
       name2=name2.substring(wss+1,name2.length());
       TextView tvLins=new TextView(context);
       tvLins.setText(name3);
       tvLins.setTextSize(14);
       if(a==0||a==2){
        tvLins.setTextColor(Color.rgb(20, 150, 193));
       }else{
        tvLins.setTextColor(Color.BLACK);
       }
       holder.tv.addView(tvLins);
       if(a==0){//评论人的id
        tvLins.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
          Intent intent = new Intent(context, MyActivity.class);
          intent.putExtra("friends_id",userid);
          context.startActivity(intent);
         }
        });
       }else if(a==2){//被回复人的id
        tvLins.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
          Intent intent = new Intent(context, MyActivity.class);
          intent.putExtra("id",id);
          context.startActivity(intent);
         }
        });
       }else if(a==3){
        tvLins.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
          
         }
        });
       }
      }
      //剩余不够一行的生成一个Textview
      TextView tv8=new TextView(context);
      tv8.setText(name2);
      tv8.setTextSize(14);
      if(a==0||a==2){
       tv8.setTextColor(Color.rgb(20, 150, 193));
      }else{
       tv8.setTextColor(Color.BLACK);
      }
      holder.tv.addView(tv8);
      if(a==0){//评论人的id
       tv8.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
         Intent intent = new Intent(context, MyActivity.class);
         intent.putExtra("id",id);
         context.startActivity(intent);
        }
       });
      }else if(a==2){//被回复人的id
       tv8.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
         Intent intent = new Intent(context, MyActivity.class);
         intent.putExtra("id",id);
         context.startActivity(intent);
        }
       });
      }else if(a==3){
       tv8.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
        }
       });
      }
     }
     
     if(a==0){//评论人的id
      tv.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
       
       }
      });
     }else if(a==2){//被回复人的id
      tv.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        
       }
      });
     }else if(a==3){
      tv.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        
       }
      });
     }

    }
    //判读剩余的字符串的宽度
    TextView tv6=new TextView(context);
    tv6.setText(name2);
    tv6.setTextSize(14);
    int wg6 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
       int hg6 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
       tv6.measure(wg6, hg6);
       //获取字符串的长度
    int w2Px=tv6.getMeasuredWidth();//px
    widthQ=w2Px;
    /*************以上为换行操作end*******************/
   }
  }

 

计算一个字符串宽度要用下面方法才准确

 TextView tv6=new TextView(context);
    tv6.setText(name2);
    tv6.setTextSize(14);
    int wg6 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
       int hg6 = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
       tv6.measure(wg6, hg6);
       //获取字符串的长度
    int w2Px=tv6.getMeasuredWidth();//px

 

这样的方法算的中文还可以,有英文的话就会有很大的误差.

 TextPaint FontPaint = new TextPaint();
//      FontPaint.setTextSize(20);
//      float ws=FontPaint.measureText(name);//d

 

 

 

0 0