android自定义控件学习(一)单行横向标签并做溢出处理

正式开发android也有一个月左右了,公司的一个小的app基本完成,没什么事干,想起了搞点事。看到别人写的自定义控件用着挺爽的,也想着自己写一个,无奈能力有限,写了第一个属于自己的自定义控件费尽了心事。废话不多说,先上来效果图。(背景控件原型知乎app,而又不同于其效果)


(知乎原型图)


(我的效果图)

下面我说下我的思路:
制作标签横向列表,通过动态添加到父布局中,父布局采用的是:HorizontalScrollView,然后通过AddView(View v) 方法添加子控件textView 。但是手机的屏幕宽度是有限的,就会出现下图中未处理溢出的情形。因此我们需要做一下处理,处理办法很简单。
通过重写HorizontalScrollView的   onLayout ( boolean paramBoolean , int paramInt1 , int paramInt2 , int paramInt3 , int paramInt4)方法来处理;onLayout 方法是来布局子控件,正好我们需要处理子控件,用这个方法再好不过了;对子控件的处里的代码也不多,下面是我的处理方法,如果有做的不妥的话,请指正。
  • 动态添加TextView
  • public void setTopic(List<Topic> list) {  
          removeAllViews();  
          this.b = false;  
          this.topics = list;  
          LinearLayoutCompat linearLayoutCompat = new LinearLayoutCompat(getContext());  
          linearLayoutCompat.setOrientation(LinearLayoutCompat.HORIZONTAL);  
          Iterator iterator = topics.iterator();  
          while (iterator.hasNext()) {  
              final Topic localTopic = (Topic) iterator.next();  
              TextView localTextView = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.text, linearLayoutCompat, false);  
              localTextView.setText(localTopic.getName());  
              localTextView.setOnClickListener(new OnClickListener() {  
                  @Override  
                  public void onClick(View v) {  
                      Toast.makeText(getContext(), localTopic.getName(), Toast.LENGTH_SHORT).show();  
                  }  
              });  
              linearLayoutCompat.addView(localTextView);  
          }  
          addView(linearLayoutCompat);  
      }  

    • 处理溢出的TextView
    @Override  
      protected void onLayout(boolean paramBoolean, int paramInt1, int paramInt2, int paramInt3, int paramInt4) {  
          super.onLayout(paramBoolean, paramInt1, paramInt2, paramInt3, paramInt4);  
          Log.e(TAG, "onLayout------------------------------" + paramBoolean);  
          if (paramBoolean) {  
              final LinearLayoutCompat linearLayout = (LinearLayoutCompat) getChildAt(0);  
              //  getChildAt(postion) ViewGroup 里面的方法 用来获取指定位置的视图,由于下边的setTopic(List<Topic> list)方法中添加的控件是  
              // 一个LinearLayoutCompat布局,所以这里获取的就是他了  
              int count = linearLayout.getChildCount();//计算一个LinearLayoutCompat布局中子控件的个数  
              TextView localTextView = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.text, linearLayout, false);  
              localTextView.setText("...");//定义一个文本内容为"..."的TextView,作为溢出内容填充  
              int width = 0;//初始化linearLayout宽度  
              for (int i = 0; i < count; i++) {//遍历所用TextView控件,并累加计算当前linearLayout宽度  
                  width += linearLayout.getChildAt(i).getWidth();  
                  if (width+localTextView.getWidth() > getWidth()) {//如果当前遍历的第i个TextView时候,linearLayout宽度大于父布局宽度  
                      linearLayout.removeViews(i - 1, count - i + 1); // 将当前TextView以后的所有TextView移除  
                      linearLayout.addView(localTextView);//添加文本内容为"..."的TextView到末尾  
                      break;  
                  }  
              }  
          }  
      }  
    需要注意的还要做一下细节处理,HorizontalScrollView 能左右滑动,我们要关闭这个功能。下面是处理方法:
  •  @Override
        public boolean onTouchEvent(MotionEvent ev) {
            return false;
        }
    就这么简单就实现,突然发现也没多难吗,耐心了解android的控件内部实现还是很重要的。
    源码下载 (项目创建使用AndroidSutdio创建)




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值