[自定义View]未读消息数角标

momochong 8年前
   <p>今天我们再来聊一聊自定义View吧</p>    <p>看看一下我们今天要完成的效果图吧!</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/603e7505fd057a1b7e68e0a31b88eb34.png"></p>    <p style="text-align: center;">简书App</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d98e20b8846441510a60ef94338710c9.png"></p>    <p style="text-align: center;">掘金App</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/637cd7f50a3e2c20fc91857947bc3db9.png"></p>    <p style="text-align: center;">新浪微博</p>    <p>然后来看一下我们的效果图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c79bee782983d71aece001ca0ec5fcbd.png"></p>    <p style="text-align: center;">自定义View</p>    <p><img src="https://simg.open-open.com/show/3b21695e80e460341acc57c40ab7b87c.gif"></p>    <p style="text-align:center">效果图</p>    <p>我们应该怎么来实现这样的自定义控件呢?</p>    <p>其实很简单,只要几行代码你就可以实现这样一个控件,具体怎么做呢,我们一步一步来。</p>    <p>首先,我们要知道,这个控件是一个组合的自定义View,上下结构,上面是ImageView,下面是TextView,然后右上角还有一个TextView</p>    <p>所以我们先把这个布局写出来</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="match_parent"      android:layout_height="wrap_content">        <ImageView          android:id="@+id/bar_iv"          android:layout_width="32dp"          android:layout_height="32dp"          android:layout_centerHorizontal="true"          android:src="@mipmap/ic_launcher" />        <TextView          android:id="@+id/bar_tv"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:layout_below="@+id/bar_iv"          android:gravity="center"          android:text="消息" />        <TextView          android:id="@+id/bar_num"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_marginLeft="-12dp"          android:layout_toRightOf="@+id/bar_iv"          android:background="@drawable/red_dot_bg"          android:text="1"          android:gravity="center"          android:textColor="#FFFFFF"          android:textSize="10dp" />  </RelativeLayout>a</code></pre>    <p>默认的TextView是方形的,不会出现圆角,我们需要给它指定一个Shape,Shape文件也很简单,请看Shape文件的代码</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <shape xmlns:android="http://schemas.android.com/apk/res/android">      <corners android:radius="180dip" />      <solid android:color="#FF0000" />      <padding          android:left="4dip"          android:right="4dip" />  </shape></code></pre>    <p>shape文件定义好之后,直接在TextView的background属性中使用就好了</p>    <p>好了,布局文件定义好了,我们来看一下如何来使用这个布局文件</p>    <p>我们需要创建一个BottomBarView并且继承Relativelayout,然后重写它的构造方法,接下来我们不需要重写onMeasure、onLayout、onDraw,我们只需要简单的一步,就可以把控件都加载出来了,请看代码:</p>    <pre>  <code class="language-java">public class BottomBarView extends RelativeLayout {        private TextView bar_num;        public BottomBarView(Context context) {          this(context, null);      }        public BottomBarView(Context context, AttributeSet attrs) {          this(context, attrs, 0);      }        public BottomBarView(Context context, AttributeSet attrs, int defStyleAttr) {          super(context, attrs, defStyleAttr);          RelativeLayout rl = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.change_color_bar, this, true);          bar_num = (TextView) rl.findViewById(R.id.bar_num);      }  }</code></pre>    <p>看到没有我也没做啥,就是把之前写的布局inflate出来,然后添加到这个自定义View里面来了,很简单吧。</p>    <p>到这里还没有完全写好,接下来我们要添加这样的功能,动态的修改右上角红色角标的显示数字,就像QQ未读消息一样,看一下我们代码是怎么写的:</p>    <pre>  <code class="language-java">public class BottomBarView extends RelativeLayout {        private int msgCount;      private TextView bar_num;        public BottomBarView(Context context) {          this(context, null);      }        public BottomBarView(Context context, AttributeSet attrs) {          this(context, attrs, 0);      }        public BottomBarView(Context context, AttributeSet attrs, int defStyleAttr) {          super(context, attrs, defStyleAttr);          RelativeLayout rl = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.change_color_bar, this, true);          bar_num = (TextView) rl.findViewById(R.id.bar_num);      }        public void setMessageCount(int count) {          msgCount = count;          if (count == 0) {              bar_num.setVisibility(View.GONE);          } else {              bar_num.setVisibility(View.VISIBLE);              if (count < 100) {                  bar_num.setText(count + "");              } else {                  bar_num.setText("99+");              }          }          invalidate();      }        public void addMsg() {          setMessageCount(msgCount + 1);      }  }</code></pre>    <p>其实就是加了一个setMessageCount方法和addMsg方法,可以动态更新未读消息的显示数量。</p>    <p>说一下我的观点吧,加载布局文件来自定义View比较省事,但是不够灵活。直接通过new TextView或者new ImageView来进行自定义控件比较麻烦,在业务逻辑不是很复杂的情况下,直接用布局文件自定义View就好了。因为我一直觉得,够用就好。</p>    <p>好了,整个自定义View就完成了,是不是很简单,效果图已经在文章开头发了</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/98932e5d0202</p>    <p> </p>