且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Android 高仿QQ滑动弹出菜单标记已读、未读消息

更新时间:2021-07-28 01:27:33

  在上一篇博客《Android 高仿微信(QQ)滑动弹出编辑、删除菜单效果,增加下拉刷新功能》里,已经带着大家学习如何使用SwipeMenuListView这一开源库实现滑动列表弹出菜单,接下来,将进一步学习,如何为不同的list item呈现不同的菜单,此处我们做一个实例:Android 高仿QQ滑动弹出菜单标记已读、未读消息,看下效果图:

Android 高仿QQ滑动弹出菜单标记已读、未读消息


1. 创建项目,并导入SwipeMenuListView类库

Android 高仿QQ滑动弹出菜单标记已读、未读消息

2. 创建消息实体bean:

public class Msg {

    public int id;

    public String title;

    public String desc;

    // false是未读;true是已读
    public boolean isRead;

    @Override
    public String toString() {
        return "Msg{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", desc='" + desc + '\'' +
                ", isRead=" + isRead +
                '}';
    }
}

注: 通过isRead字段,我们区分菜单显示“设为已读”“设为未读”;


3. 创建列表显示的Adapter,重写其中的getItemViewType方法:

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * my msgs list adapter
 */
public class MyMsgAdapter extends BaseAdapter {

    private Activity mContext;

    private LayoutInflater mInflater;

    private List<Msg> mDatas;

    public MyMsgAdapter(Activity context, List<Msg> datas) {
        mContext = context;
        mInflater = LayoutInflater.from(mContext);
        mDatas = datas;
    }

    @Override
    public int getCount() {
        return (mDatas != null ? mDatas.size() : 0);
    }

    @Override
    public Object getItem(int position) {
        return (mDatas != null ? mDatas.get(position) : null);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        Msg myMsg = mDatas.get(position);
        boolean isRead = myMsg.isRead;
        if (isRead) {
            return 0;
        } else {
            return 1;
        }
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            // 下拉项布局
            convertView = mInflater.inflate(R.layout.list_item_my_msg, null);

            holder = new ViewHolder();

            holder.img_msg = (ImageView) convertView.findViewById(R.id.img_msg);
            holder.text_msg_user_name = (TextView) convertView.findViewById(R.id.text_msg_user_name);
            holder.text_msg_infos = (TextView) convertView.findViewById(R.id.text_msg_infos);

            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        final Msg myMsg = mDatas.get(position);

        if (myMsg != null) {

            if (myMsg.isRead) {//未读
                holder.img_msg.setImageResource(R.mipmap.readed_msg_img);
            } else {
                holder.img_msg.setImageResource(R.mipmap.unread_msg_img);
            }

            holder.text_msg_user_name.setText(myMsg.title);
            holder.text_msg_infos.setText(myMsg.desc);
        }

        return convertView;
    }

    class ViewHolder {

        ImageView img_msg;

        TextView text_msg_user_name;

        TextView text_msg_infos;
    }
}

注: 此处重写了父类中的getItemViewType方法,该方法中,我们根据Msg的isRead字段来判断返回值的是0还是1; 之后,我们将根据该返回值,来判断list item的菜单是何种类型!


2. 根据ItemViewType,创建滑动菜单:

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.TypedValue;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;

import com.apkfuns.logutils.LogUtils;
import com.baoyz.swipemenulistview.SwipeMenu;
import com.baoyz.swipemenulistview.SwipeMenuCreator;
import com.baoyz.swipemenulistview.SwipeMenuItem;
import com.baoyz.swipemenulistview.SwipeMenuListView;

import java.util.ArrayList;
import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnItemClick;

public class MainActivity extends AppCompatActivity {

    // 方案列表
    @Bind(R.id.listViewMyMsgs)
    public SwipeMenuListView listViewMyMsgs;

    private MyMsgAdapter msgAdapter;

    // 消息集合
    private List<Msg> msgs;

    // 要删除的数据
    private Msg dMsg;

    // 要修改的数据
    private int oPos;

    private Msg oMyMsg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);

        msgs = new ArrayList<Msg>();

        Msg msg1 = new Msg();
        msg1.id = 1;
        msg1.title = "上邪";
        msg1.desc = "我欲与君相知,长命无绝衰";
        msg1.isRead = false;

        Msg msg2 = new Msg();
        msg2.id = 2;
        msg2.title = "爱在记忆中找你";
        msg2.desc = "如果可以恨你,全力痛恨你,连遇上亦要躲避";
        msg2.isRead = true;

        msgs.add(msg1);
        msgs.add(msg2);

        msgAdapter = new MyMsgAdapter(this, msgs);
        listViewMyMsgs.setAdapter(msgAdapter);

        createMenu();
    }

    /**
     * 删除某个消息
     *
     * @param position
     */
    private void deleteMsg(int position) {
        // DoDeleteMsgRequest(String id,Handler mHandler, int reqCode)
        dMsg = msgs.get(position);
        if (dMsg != null) {
            Toast.makeText(MainActivity.this, "删除 : " + dMsg, Toast.LENGTH_SHORT).show();

            msgs.remove(dMsg);
            msgAdapter.notifyDataSetChanged();
        }
    }

    /**
     * 标记已读和未读
     *
     * @param position
     */
    private void readMsg(int position) {
        //DoReadMsgRequest(String id, String isRead, Handler mHandler, int reqCode)
        oPos = position;
        oMyMsg = msgs.get(position);
        if (oMyMsg != null) {
            msgs.get(position).isRead = !msgs.get(position).isRead;

            msgAdapter.notifyDataSetChanged();
        }
    }

    private void createMenu() {
        // step 1. create a MenuCreator
        SwipeMenuCreator creator = new SwipeMenuCreator() {
            @Override
            public void create(SwipeMenu menu) {
                switch (menu.getViewType()) {
                    case 0:// 未读
                        createMenu1(menu);
                        break;
                    case 1:// 已读
                        createMenu2(menu);
                        break;
                }
            }

            private void createMenu1(SwipeMenu menu) {
                SwipeMenuItem unreadItem = new SwipeMenuItem(
                        getApplicationContext());
                unreadItem.setId(1);
                unreadItem.setBackground(new ColorDrawable(Color.parseColor("#555555")));
                unreadItem.setWidth(dp2px(90));
                unreadItem.setTitle("标为已读");
                unreadItem.setTitleSize(16);
                unreadItem.setTitleColor(Color.parseColor("#FFFFFF"));
                menu.addMenuItem(unreadItem);

                SwipeMenuItem deleteItem = new SwipeMenuItem(
                        getApplicationContext());
                deleteItem.setId(0);
                deleteItem.setBackground(new ColorDrawable(Color.parseColor("#EF4B3A")));
                deleteItem.setWidth(dp2px(90));
                deleteItem.setTitle("删除");
                deleteItem.setTitleSize(16);
                deleteItem.setTitleColor(Color.parseColor("#FFFFFF"));
                menu.addMenuItem(deleteItem);
            }

            private void createMenu2(SwipeMenu menu) {
                SwipeMenuItem readedItem = new SwipeMenuItem(
                        getApplicationContext());
                readedItem.setId(2);
                readedItem.setBackground(new ColorDrawable(Color.parseColor("#555555")));
                readedItem.setWidth(dp2px(90));
                readedItem.setTitle("标记未读");
                readedItem.setTitleSize(16);
                readedItem.setTitleColor(Color.parseColor("#FFFFFF"));
                menu.addMenuItem(readedItem);

                SwipeMenuItem deleteItem = new SwipeMenuItem(
                        getApplicationContext());
                deleteItem.setId(0);
                deleteItem.setBackground(new ColorDrawable(Color.parseColor("#EF4B3A")));
                deleteItem.setWidth(dp2px(90));
                deleteItem.setTitle("删除");
                deleteItem.setTitleSize(16);
                deleteItem.setTitleColor(Color.parseColor("#FFFFFF"));
                menu.addMenuItem(deleteItem);
            }
        };
        // set creator
        listViewMyMsgs.setMenuCreator(creator);

        // step 2. listener item click event
        listViewMyMsgs.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {

                SwipeMenuItem menuItem = menu.getMenuItem(index);
                int id = menuItem.getId();
                switch (id) {
                    case 0:
                        LogUtils.e("删除 :" + position);
                        deleteMsg(position);
                        break;
                    case 1:
                        LogUtils.e("标记未读 :" + position);
                        readMsg(position);
                        break;
                    case 2:
                        LogUtils.e("标为已读 :" + position);
                        readMsg(position);
                        break;
                }
                return false;
            }
        });
    }

    @OnItemClick(R.id.listViewMyMsgs)
    public void onItemClick(AdapterView<?> parent, View view, int position,
                            long id) {
        Msg myMsg = (Msg) parent.getAdapter().getItem(
                position);
        if (myMsg != null) {

            if (myMsg.isRead) { // 如果是未读,需要标记为已读
                readMsg(position);
            }
        }
    }

    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getResources().getDisplayMetrics());
    }
}


注: 着重看下SwipeMenuCreator接口中的public void create(SwipeMenu menu)方法,通过menu.getViewType()方法,我们可以得到该list item的viewType,而这个viewType,使我们刚刚在Adapter自己定义的,所以此时,只需要判断自己所定义的viewType值,并根据viewType来创建菜单即可!


如此这般,便可实现类似QQ滑动弹出菜单标记已读、未读消息功能啦,欢迎指正!

如有疑问,欢迎进QQ群:487786925( Android研发村 )

源码下载地址:https://github.com/zuiwuyuan/SwipeRefreshStickyList