Android小细节IT@程序员猿媛程序员

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

2019-04-02  本文已影响1780人  yeyecan

今天来实现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
转载请标明出处

上一篇下一篇

猜你喜欢

热点阅读