[自定义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>