android 系统消息界面(仿bilibili)实现列表多选单
2019-04-02 本文已影响1780人
yeyecan
今天来实现android的系统消息界面,首先要实现消息列表、消息分类以及批量删除消息、全选等功能,在这里我们先看一下哔哩哔哩的页面。
再来看看我们要实现的最终效果:
效果.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
转载请标明出处