LitePal+RecyclerView+checkBox实现便签功能(仿小米便签)

来源:互联网 发布:js点击弹出再点击隐藏 编辑:程序博客网 时间:2024/05/17 22:09

费时两天,主要难点在RecyclerView和CheckBox的长按事件上。

上代码:

Note的JavaBean:

package com.example.jarvist.remember;import org.litepal.crud.DataSupport;import java.io.Serializable;import java.util.Date;/** * Created by Jarvist on 2017/8/24. *///传递对象要接入Serializable接口public class Note extends DataSupport implements Serializable {    private int id;    private String content;    private Date date;    private boolean checked;    public boolean isChecked() {        return checked;    }    public void setChecked(boolean checked) {        this.checked = checked;    }    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }    public Date getDate() {        return date;    }    public void setDate(Date date) {        this.date = date;    }}

RecyclerView所需的Adapter

package com.example.jarvist.remember;import android.content.Context;import android.content.Intent;import android.support.design.widget.Snackbar;import android.support.v7.widget.CardView;import android.support.v7.widget.RecyclerView;import android.text.Layout;import android.text.SpannableString;import android.text.Spanned;import android.text.style.TextAppearanceSpan;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.LinearLayout;import android.widget.TextView;import java.text.SimpleDateFormat;import java.util.HashMap;import java.util.List;import java.util.Map;/** * Created by Jarvist on 2017/8/24. */public class NoteAdapter extends RecyclerView.Adapter <NoteAdapter.ViewHolder>            implements View.OnClickListener,View.OnLongClickListener{    private List<Note> mNoteList;    private Context mContext;    private RecyclerViewOnItemClickListener onItemClickListener;    //multiple choice    public boolean MUL_tag = false;    //checkbox situation map 保存CheckBox选中状态    private HashMap<Integer,Boolean> ischecked = new HashMap<Integer, Boolean>();    public NoteAdapter (List<Note> noteList){        mNoteList = noteList;        initMaps();    }    public void initMaps(){        for(int i = 0; i <mNoteList.size(); i++){            ischecked.put(i,false);        }    }    static class ViewHolder extends RecyclerView.ViewHolder{        CardView cardView;        TextView contentView;        TextView dateView;        CheckBox checkBox;        public ViewHolder(View v){            super(v);            cardView = (CardView)v.findViewById(R.id.cardview);            contentView = (TextView)v.findViewById(R.id.content);            dateView = (TextView)v.findViewById(R.id.date);            checkBox = (CheckBox)v.findViewById(R.id.checkbox);        }    }    @Override    public ViewHolder onCreateViewHolder (final ViewGroup parent, int viewType){        if(mContext == null){            mContext = parent.getContext();        }        final View view = LayoutInflater.from(mContext).inflate(R.layout.note_item,parent,false);        final ViewHolder viewHolder = new ViewHolder(view);        viewHolder.cardView.setOnClickListener(this);        viewHolder.cardView.setOnLongClickListener(this);        return viewHolder;    }    @Override    public void onBindViewHolder(final ViewHolder holder, final int position){        Note note = mNoteList.get(position);        String values = note.getContent();        holder.contentView.setText(values);        holder.dateView.setText(new SimpleDateFormat("yyyy/MM/dd    HH:mm:ss").format(note.getDate()));        //多选状态,CheckBox显示,否则不显示        if(MUL_tag) {            holder.checkBox.setVisibility(View.VISIBLE);        }        else {            holder.checkBox.setVisibility(View.INVISIBLE);        }        //注意用setTag保存position信息        holder.cardView.setTag(position);        //判断CheckBox,保存选中信息        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                ischecked.put(position,isChecked);            }        });        if(ischecked.get(position) == null)            ischecked.put(position,false);        //CheckBox状态        holder.checkBox.setChecked(ischecked.get(position));    }    @Override    public int getItemCount(){        return mNoteList.size();    }    //设置单击传入position    @Override    public void onClick(View v){        if(onItemClickListener != null)        {            onItemClickListener.onItemClickListener(v,(Integer)v.getTag());        }    }    //长按传入position    @Override    public boolean onLongClick(View v){        initMaps();        return onItemClickListener != null && onItemClickListener.onLongClickListener(v,(Integer)v.getTag());        }    //创建监听事件    public void setRecycleViewOnItemClickListener(RecyclerViewOnItemClickListener onItemClickListener){        this.onItemClickListener = onItemClickListener;    }    //设置CheckBox显示状态    public void setCheckBox(){        MUL_tag = !MUL_tag;    }    //设置选中保存状态    public void setSelection(int position){        if(ischecked.get(position))            ischecked.put(position,false);        else            ischecked.put(position,true);        notifyItemChanged(position);    }    //getMap()以便MainActivity中获取Map    public HashMap<Integer,Boolean> getMap(){        return ischecked;    }    //接口,以便MainActivity中进行调用重写    public interface RecyclerViewOnItemClickListener    {        void onItemClickListener(View view,int position);        boolean onLongClickListener(View view, int position);    }}

MainActivity:

package com.example.jarvist.remember;import android.content.DialogInterface;import android.content.Intent;import android.graphics.Color;import android.support.design.widget.FloatingActionButton;import android.support.v7.app.ActionBar;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.support.v7.widget.Toolbar;import android.view.MotionEvent;import android.view.View;import android.widget.ImageButton;import android.widget.TextView;import org.litepal.crud.DataSupport;import java.util.List;import java.util.Map;public class MainActivity extends AppCompatActivity {    private int status;//判断读写    public static final int WRITE = 1;// 1是新增便签,2是读取已有便签    public static final int READ = 2;    private RecyclerView recyclerView;    private List<Note> noteList;    private NoteAdapter adapter;    private ActionBar actionBar;    private boolean showboxTag = false;//判断是否显示CheckBox    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);        final ImageButton deletebtn = (ImageButton)findViewById(R.id.menu1);        TextView title = (TextView)findViewById(R.id.title);        FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);        fab.setBackgroundColor(Color.YELLOW);        recyclerView = (RecyclerView)findViewById(R.id.recyclerView);        setSupportActionBar(toolbar);        actionBar = getSupportActionBar();        if(actionBar != null){            //左上角菜单键            actionBar.setDisplayHomeAsUpEnabled(true);            actionBar.setHomeAsUpIndicator(R.drawable.menu3);            actionBar.setDisplayShowTitleEnabled(false);        }        noteList = DataSupport.order("date desc").find(Note.class);        fab.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(MainActivity.this,WriteActivity.class);                status = 1;                intent.putExtra("Status", status);//传递信息                startActivity(intent);            }        });        deletebtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);//创建dialog                dialog.setTitle("删除便签");                dialog.setMessage("您确定要删除所选便签?");                dialog.setCancelable(false);                dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        // 获取保存通过CheckBox选中的便签,选中状态由adapter中的map保存,通过getMap()获取                        Map<Integer,Boolean> map = adapter.getMap();                        //从后往前删除                        for(int i=map.size()-1; i>=0; i--){                            if(map.get(i)){                                //i为CheckBox选中的view的position                                int id = noteList.get(i).getId();                                deleteData(id);                                //noteList中移除                                noteList.remove(i);                                //adapter重新设置item                                adapter.notifyItemRemoved(i);                            }                        }                        //adapter长度重新设置                        adapter.notifyItemRangeChanged(0,noteList.size());                        //删除后回到正常状态,CheckBox不显示,map重新归false                        adapter.MUL_tag  = false;                        adapter.initMaps();                        showboxTag = false;                        adapter.notifyDataSetChanged();                    }                });                dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        dialog.dismiss();//取消dialog                    }                });                dialog.show();            }        });        deletebtn.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                //delete键按下后背景发生变化                if(event.getAction() == MotionEvent.ACTION_DOWN)                    deletebtn.setBackgroundColor(getResources().getColor(R.color.colorbg1));                else if(event.getAction() == MotionEvent.ACTION_UP)                    deletebtn.setBackgroundColor(getResources().getColor(R.color.colorbg2));                return false;            }        });        //创建adapter        adapter = new NoteAdapter(noteList);        //设置监听        adapter.setRecycleViewOnItemClickListener(new NoteAdapter.RecyclerViewOnItemClickListener() {            @Override            public void onItemClickListener(View view, int position) {                Intent intent = new Intent(MainActivity.this,WriteActivity.class);                Note note = noteList.get(position);                status = 2;                intent.putExtra("Status", status);                intent.putExtra("Content",note);//传递对象                startActivity(intent);            }            //长按时间            @Override            public boolean onLongClickListener(View view, int position) {                //长按显示CheckBox,并且长按位置选中该便签吖                adapter.setSelection(position);                adapter.setCheckBox();                adapter.notifyDataSetChanged();                showboxTag = true;                return true;            }        });        //瀑布流布局        StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);        recyclerView.setLayoutManager(manager);        recyclerView.setAdapter(adapter);    }    //resume    @Override    protected void onResume(){        super.onResume();        //status归零        status = 0;        //noteList清空        noteList.clear();        //创建新list读取并按时间倒序排列        List<Note> newList = DataSupport.order("date desc").find(Note.class);        //将新list加入到noteList中        noteList.addAll(newList);        //adapter中CheckBox初始化        adapter.MUL_tag  = false;        adapter.initMaps();        showboxTag = false;        adapter.notifyDataSetChanged();    }    public void deleteData(int id){        DataSupport.deleteAll(Note.class,"id = ?",String.valueOf(id));    }    @Override    public void onBackPressed(){        //处于多选状态,按下返回键回到正常状态        if(showboxTag){            adapter.MUL_tag  = false;            adapter.initMaps();            adapter.notifyDataSetChanged();            showboxTag = false;        }        //否则调用父类方法        else            super.onBackPressed();    }}

WriteActivity:

package com.example.jarvist.remember;import android.content.Intent;import android.media.Image;import android.support.v7.app.ActionBar;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.KeyEvent;import android.view.MenuItem;import android.view.MotionEvent;import android.view.View;import android.widget.EditText;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.LinearLayout;import java.util.Date;public class WriteActivity extends AppCompatActivity {    private ActionBar actionBar;    private int noteID;    private int status;    private EditText contentText;    private ImageButton menuView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_write);        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);        contentText = (EditText)findViewById(R.id.editText);        menuView = (ImageButton) findViewById(R.id.menu2);        setSupportActionBar(toolbar);        actionBar = getSupportActionBar();        if(actionBar != null){            actionBar.setDisplayHomeAsUpEnabled(true);            actionBar.setDisplayShowTitleEnabled(false);        }        Intent intent = getIntent();        status = intent.getIntExtra("Status",0);        if(status == MainActivity.READ){            //读操作            Note note = (Note)intent.getSerializableExtra("Content");            //显示内容和游标放到内容末端            contentText.setText(note.getContent());            contentText.setSelection(note.getContent().length());            //获取id            noteID = note.getId();        }        //按钮按下背景变化        menuView.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                if(event.getAction() == MotionEvent.ACTION_DOWN)                    menuView.setBackgroundColor(getResources().getColor(R.color.colorbg1));                else if(event.getAction() == MotionEvent.ACTION_UP)                    menuView.setBackgroundColor(getResources().getColor(R.color.colorbg2));                return false;            }        });        menuView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //新增便签                if(status == MainActivity.WRITE){                    Intent intent1 = new Intent(WriteActivity.this,MainActivity.class);                    startActivity(intent1);                    saveData();                }                else if(status == MainActivity.READ){                    //读取便签后更新数据                    Intent intent1 = new Intent(WriteActivity.this,MainActivity.class);                    startActivity(intent1);                    updateData();                }                finish();            }        });    }    //左上角home键    @Override    public boolean onOptionsItemSelected(MenuItem item){        switch (item.getItemId()){            case android.R.id.home:                Intent intent = new Intent(WriteActivity.this,MainActivity.class);                startActivity(intent);                break;            default:                break;        }        return true;    }    public void updateData(){        if(!(contentText.getText().toString().equals(""))){            Note note = new Note();            note.setDate(new Date());            note.setContent(contentText.getText().toString());            note.update(noteID);        }    }    public void saveData(){        if(!(contentText.getText().toString().equals("")) ){            Note note = new Note();            note.setDate(new Date());            note.setContent(contentText.getText().toString());            note.save();        }    }}

note_Item.xml:

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/cardview"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_margin="5dp"    app:cardCornerRadius="4dp">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="vertical"            >            <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:text="hello"                android:layout_marginTop="5dp"                android:layout_marginStart="5dp"                android:textSize="15sp"                android:textColor="#000"                android:id="@+id/content"/>        </LinearLayout>        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal">            <android.support.design.widget.CoordinatorLayout                android:layout_height="match_parent"                android:layout_width="wrap_content">                <TextView                    android:layout_marginTop="10dp"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_marginStart="15dp"                    android:layout_marginBottom="10dp"                    android:layout_gravity="bottom|end"                    android:text="world"                    android:textSize="10sp"                    android:id="@+id/date"/>            </android.support.design.widget.CoordinatorLayout>            <android.support.design.widget.CoordinatorLayout                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1">                <CheckBox                    android:id="@+id/checkbox"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:scaleX="0.85"                    android:scaleY="0.85"                    android:layout_gravity="bottom|end"                    android:visibility="gone" />            </android.support.design.widget.CoordinatorLayout>        </LinearLayout>    </LinearLayout></android.support.v7.widget.CardView>
MainActivity.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.design.widget.CoordinatorLayout        android:layout_width="match_parent"        android:layout_height="match_parent">        <android.support.design.widget.AppBarLayout            android:layout_width="match_parent"            android:layout_height="wrap_content">            <android.support.v7.widget.Toolbar                android:layout_width="match_parent"                android:layout_height="?attr/actionBarSize"                android:id="@+id/toolbar"                android:background="@color/colorPrimary"                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"                app:popupTheme="@style/Theme.AppCompat.Light"                app:layout_scrollFlags="scroll|enterAlways|snap">                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:id="@+id/title"                    android:text="Remember"                    android:textColor="#202020"                    android:textSize="18sp"                    android:layout_gravity="center"/>                <ImageButton                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:id="@+id/menu1"                    android:background="@null"                    android:src="@drawable/delete2"                    android:layout_marginEnd="10dp"                    android:layout_gravity="end"/>            </android.support.v7.widget.Toolbar>        </android.support.design.widget.AppBarLayout>        <android.support.v7.widget.RecyclerView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:id="@+id/recyclerView"            app:layout_behavior="@string/appbar_scrolling_view_behavior">        </android.support.v7.widget.RecyclerView>        <android.support.design.widget.FloatingActionButton            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/fab"            android:background="#ffc002"            android:layout_gravity="bottom|end"            android:src="@drawable/add"            android:layout_marginBottom="10dp"            android:layout_marginEnd="10dp"            app:elevation="8dp"/>    </android.support.design.widget.CoordinatorLayout></LinearLayout>


WriteActivity.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.design.widget.CoordinatorLayout        android:layout_width="match_parent"        android:layout_height="match_parent">        <android.support.design.widget.AppBarLayout            android:layout_width="match_parent"            android:layout_height="wrap_content">            <android.support.v7.widget.Toolbar                android:layout_width="match_parent"                android:layout_height="?attr/actionBarSize"                android:id="@+id/toolbar"                android:background="@color/colorPrimary"                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"                app:popupTheme="@style/Theme.AppCompat.Light">                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:id="@+id/title"                    android:text="Remember"                    android:textColor="#202020"                    android:textSize="17sp"                    android:layout_gravity="center"/>                <ImageButton                    android:layout_width="40dp"                    android:layout_height="40dp"                    android:id="@+id/menu2"                    android:src="@drawable/check1"                    android:background="@null"                    android:layout_marginEnd="5dp"                    android:layout_gravity="right"/>            </android.support.v7.widget.Toolbar>        </android.support.design.widget.AppBarLayout>        <EditText            android:layout_width="match_parent"            android:layout_height="match_parent"            android:id="@+id/editText"            android:cursorVisible="true"            android:gravity="top"            android:background="@null"            android:layout_margin="6dp"            app:layout_behavior="@string/appbar_scrolling_view_behavior"            />    </android.support.design.widget.CoordinatorLayout></LinearLayout>

Github项目地址:

https://github.com/JarvistFth/Rememberhttps://github.com/JarvistFth/Remember

点击打开链接


第一个练手的app,感谢郭神的书。