美文网首页Android小细节IT@程序员猿媛程序员
android 系统消息界面(仿bilibili)实现列表多选单

android 系统消息界面(仿bilibili)实现列表多选单

作者: yeyecan | 来源:发表于2019-04-02 12:02 被阅读1780次

    今天来实现android的系统消息界面,首先要实现消息列表、消息分类以及批量删除消息、全选等功能,在这里我们先看一下哔哩哔哩的页面。

    Bilibili.gif
    再来看看我们要实现的最终效果:
    效果.gif

    话不多说,让我们开始吧。

    布局页面的实现

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".activity.NotificationActivity">
    
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#5BC0DE">
    
    
            <android.support.v7.widget.Toolbar
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                android:id="@+id/toolbar"
                app:titleTextColor="@color/white"
                app:layout_scrollFlags="scroll|enterAlways"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize">
    
            </android.support.v7.widget.Toolbar>
    
            <RelativeLayout
                android:background="@color/white"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_30">
    
                <LinearLayout
                    android:id="@+id/line_not_compile"
                    android:layout_centerVertical="true"
                    android:layout_alignParentRight="true"
                    android:layout_marginRight="@dimen/dp_15"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent">
                    <TextView
                        android:layout_marginLeft="@dimen/dp_10"
                        android:layout_gravity="center"
                        android:layout_marginRight="@dimen/dp_10"
                        android:id="@+id/text_not_compile"
                        android:textColor="@color/colorAcceet"
                        android:text="编辑"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        />
                </LinearLayout>
            </RelativeLayout>
    
        </android.support.design.widget.AppBarLayout>
    
        <LinearLayout
            android:orientation="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swf_not_getdata"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recy_not_list"
            android:background="@color/back"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            
        </android.support.v7.widget.RecyclerView>
    
        </android.support.v4.widget.SwipeRefreshLayout>
        </LinearLayout>
    
        <RelativeLayout
            app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
            android:id="@+id/Rel_notbottom"
            android:background="@color/white"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_50">
    
            <CheckBox
                android:id="@+id/checkbox_not_checkall"
                android:layout_marginLeft="@dimen/dp_20"
                android:layout_centerVertical="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
    
            <TextView
                android:layout_centerVertical="true"
                android:layout_marginLeft="@dimen/dp_15"
                android:text="全选"
                android:layout_toRightOf="@+id/checkbox_not_checkall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="@dimen/sp_18"
                />
    
            <TextView
                android:id="@+id/text_not_delete"
                android:layout_marginRight="@dimen/dp_15"
                android:textColor="@color/umeng_comm_lv_header_color2"
                android:layout_centerVertical="true"
                android:layout_alignParentRight="true"
                android:textSize="@dimen/sp_18"
                android:text="删除"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
    
                />
        </RelativeLayout>
    </android.support.design.widget.CoordinatorLayout>
    

    以上是布局页面的代码,首先布局用的是CoordinatorLayout作为根布局,这样我们的标题可以实现上滑隐藏,然后一个线性布局,里面放着下拉刷新控件包裹着RecyclerView(也可以按照自己喜好换成listview,推荐RecyclerView),其次,我们点击编辑时候呢,必须要在底部出现一个全选和删除的页面类似于这样:

    img.png
    在这里,考虑到如果直接使用visibility属性来控制呢,会和我们的可隐藏标题冲突,所以这里我使用了BottomSheetBehavior,抽屉式布局来控制它的出现和隐藏。(关于BottomSheetBehavior我会在下一篇文章中讲解其用处)。这样我们的布局页面就基本完成了。

    为列表填充数据

    我们先为数据创建一个映射,然后实现get和set方法

    public class NotificationEntity {
            int id;
            String not_titel;
            String not_content;
            String not_time;
            boolean isshow;
            boolean ischeck;
    
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public boolean isIsshow() {
            return isshow;
        }
    
        public void setIsshow(boolean isshow) {
            this.isshow = isshow;
        }
    
        public String getNot_titel() {
            return not_titel;
        }
    
        public void setNot_titel(String not_titel) {
            this.not_titel = not_titel;
        }
    
        public String getNot_content() {
            return not_content;
        }
    
        public void setNot_content(String not_content) {
            this.not_content = not_content;
        }
    
        public String getNot_time() {
            return not_time;
        }
    
        public void setNot_time(String not_time) {
            this.not_time = not_time;
        }
    
        public boolean isIscheck() {
            return ischeck;
        }
    
        public void setIscheck(boolean ischeck) {
            this.ischeck = ischeck;
        }
    
    }
    

    因为是假数据,所以就创建了五个属性,分别是id,通知标题,通知内容,通知时间,是否显示状态,是否选中状态。
    再来看我们的item布局代码:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
    
        <CheckBox
            android:visibility="gone"
            android:id="@+id/check_not_itme"
            android:layout_marginLeft="@dimen/dp_20"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true" />
    
        <TextView
            android:id="@+id/text_nottitle_item"
            android:paddingRight="@dimen/dp_5"
            android:text="独家直播!雪未来第十年演唱会"
            android:layout_toRightOf="@+id/check_not_itme"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dp_10"
            android:layout_marginTop="@dimen/dp_20"
            android:textColor="@color/title_black"
            android:textSize="@dimen/sp_18"
            />
    
        <TextView
            android:id="@+id/text_notcontent_item"
            android:paddingRight="@dimen/dp_5"
            android:text="在雪未来(SNOW MIKU)不如第10年之际,bilibili将独家线上放送夜间演唱会,给你一个冰雪之夜!"
            android:layout_alignLeft="@+id/text_nottitle_item"
            android:layout_below="@+id/text_nottitle_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/dp_20"
            />
    
        <TextView
            android:id="@+id/text_nottime_item"
            android:layout_below="@+id/text_notcontent_item"
            android:layout_alignParentRight="true"
            android:layout_marginRight="@dimen/dp_5"
            android:layout_marginTop="@dimen/dp_5"
            android:layout_marginBottom="@dimen/dp_10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="两天前"
            />
    
        <View
            android:layout_below="@+id/text_nottime_item"
            android:layout_marginTop="@dimen/dp_10"
            android:background="@color/darkgray"
            android:layout_width="match_parent"
            android:layout_height="0.1dp">
    
        </View>
    </RelativeLayout>
    
    

    item布局很简单,一个隐藏的checkbox,以及标题内容加时间,这个可以自己定义。

    接下来进入重头戏,适配器的代码:

     public static class NotificationAdapter extends RecyclerView.Adapter<NotificationAdapter.Viewholder> {
            Context context;
            List<NotificationEntity> list;
            public NotificationAdapter(Context context, List<NotificationEntity> list) {
                this.context = context;
                this.list = list;
            }
    
    
            @NonNull
            @Override
            public NotificationAdapter.Viewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                if(context==null){
                    context = parent.getContext();
                }
                View view = LayoutInflater.from(context).inflate(R.layout.item_notification, parent, false);
                final NotificationAdapter.Viewholder holder = new NotificationAdapter.Viewholder(view);
                return holder;
            }
    
            @Override
            public void onBindViewHolder(@NonNull final NotificationAdapter.Viewholder holder, final int position) {
                final NotificationEntity notification =  list.get(position);
                holder.text_notcontent_item.setText(notification.getNot_content());
                holder.text_nottitle_item.setText(notification.getNot_titel());
                holder.text_nottime_item.setText(notification.getNot_time());
                if(notification.isIsshow()){
                    holder.check_not_itme.setVisibility(View.VISIBLE);
                }else {
                    holder.check_not_itme.setVisibility(View.GONE);
                }
    
                if(notification.isIscheck()){
                    holder.check_not_itme.setChecked(true);
                }else {
                    holder.check_not_itme.setChecked(false);
                }
    
    
                holder.check_not_itme.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(holder.check_not_itme.isChecked()){
                            notification.setIscheck(true);
                        }else {
                            notification.setIscheck(false);
                        }
                    }
                });
    
    
    
                holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(notification.isIsshow()){
                            if(holder.check_not_itme.isChecked()){
                                notification.setIscheck(false);
                                holder.check_not_itme.setChecked(false);
                            }else {
                                notification.setIscheck(true);
                                holder.check_not_itme.setChecked(true);
                            }
                        }else {
    
                        }
                    }
                });
            }
    
            @Override
            public int getItemCount() {
                return list.size();
            }
    /**
     *
     *@作者 Administrator
     *@时间 2019/4/1 0001 下午 4:00
     *  批量删除
     */
            public void deleteItem(){
                Iterator<NotificationEntity> iterator = list.iterator();
                while (iterator.hasNext()){
                    NotificationEntity notificationEntity = iterator.next();
                    if(notificationEntity.isIscheck()){
                        iterator.remove();
                    }
                }
                notifyDataSetChanged();
            }
    /**
     *
     *@作者 shuye
     *@时间 2019/4/1 0001 下午 4:00
     *  全选所有的通知
     */
            public void chechall(boolean t){
                Iterator<NotificationEntity> iterator = list.iterator();
                while (iterator.hasNext()){
                    NotificationEntity notificationEntity = iterator.next();
                    if(t){
                        if(!notificationEntity.isIscheck()){
                            notificationEntity.setIscheck(true);
                        }
                    }else {
                        if (notificationEntity.isIscheck()){
                            notificationEntity.setIscheck(false);
                        }
                    }
                }
                notifyDataSetChanged();
            }
       /**
        *
        *@作者 shuye
        *@时间 2019/4/1 0001 下午 4:06
        *  是否显示单选框
        */     
            public void isshowcheck(boolean t){
                Iterator<NotificationEntity> iterator = list.iterator();
                while (iterator.hasNext()){
                    NotificationEntity notificationEntity = iterator.next();
                    if(t){
                        if(!notificationEntity.isIsshow()){
                            notificationEntity.setIsshow(true);
                        }
                    }else {
                        if (notificationEntity.isIsshow()){
                            notificationEntity.setIsshow(false);
                        }
                    }
                }
                notifyDataSetChanged();
            }
    
    
            public class Viewholder extends RecyclerView.ViewHolder {
                TextView text_nottitle_item,text_notcontent_item,text_nottime_item;
                CheckBox check_not_itme;
                RelativeLayout relativeLayout;
                public Viewholder(@NonNull View itemView) {
                    super(itemView);
                    relativeLayout = (RelativeLayout) itemView;
                    text_nottitle_item = itemView.findViewById(R.id.text_nottitle_item);
                    text_notcontent_item = itemView.findViewById(R.id.text_notcontent_item);
                    text_nottime_item = itemView.findViewById(R.id.text_nottime_item);
                    check_not_itme = itemView.findViewById(R.id.check_not_itme);
                }
            }
        }
    

    这里呢主要是要点击checkbox和点击item都可以实现选中的效果,所以要加上判断是否被选中,但是在item的点击事件中,我们还要判断这个item的checkbox是否是显示状态的,是的话才执行相应的点击逻辑。然后就是批量删除和全选功能,两个逻辑基本一样,通过迭代器来循环判断item的状态,并通知列表刷新。

    以上就简单实现了消息通知的页面和数据处理,大家可以根据自己的需求要修改页面,实现其他的功能。

    相关的源码已上传到github,欢迎star,感谢大家支持:
    地址:https://github.com/shuyecan/Notification
    转载请标明出处

    相关文章

      网友评论

        本文标题:android 系统消息界面(仿bilibili)实现列表多选单

        本文链接:https://www.haomeiwen.com/subject/gklwbqtx.html