这篇博客用来简单复习一下SQLite以及实现RecyclerView的侧滑Item删除。
这个Demo整体思路就是将一个人的姓名和金钱存进数据库,并将所有存进数据库的数据用RecyclerView显示出来,然后加上侧滑删除的实现。
1.SQLiite
1.1数据的准备
这里首先一开始是前段时间找工作遇到的上机复试题。
点击按钮,显示出一个Dialog,然后输入15232.20,得到一万五千二百三十二元二角。
虽然很简单,但自己处理的不好。这里是后来自己又做了一次,稍微比复试好一些。思路就是首先在输入金钱额度的时候,将EditText输入的属性设置为只可以输入数字和小数点。
tie.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL);
然后对输入的数字进行判断是否含有小数点。如果含有小数点,就利用Stirng.split()方法,将String拆分。这里需要注意的是,String.split(“.”)是无效的。
String [] s = str.split("\\.");
需要使用转译字符 。split方法的参数可以为正则表达式。在正则表达式中” . ” 代表任意字符。之后便是对拆分的字符串的处理。
界面很简单就是有几个按钮,一个保存按钮,一个查看。保存就是将输入的人的名字和金额存进数据库。查看按钮会打开一个新的Activity来展示数据库中有的数据。
1.2DBHelper
Android中提供了一个SQLiteOpenHelper类,直接继承这个类。
public class DBHelper extends SQLiteOpenHelper {
private static final String DEFAULT_NAME = "app_1_person.db";
private static final int DEFAULT_VERSION = 1;
public DBHelper(Context context) {
super(context,DEFAULT_NAME, null, DEFAULT_VERSION);
}
/**
* 第一次被创建时会调用
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
"CREATE TABLE IF NOT EXISTS person" +
"(_id INTEGER PRIMARY KEY AUTOINCREMENT , name VARCHAR(20) , money TEXT)"
);
}
/**
* 版本更新时 会调用
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion){
//TODO
}
}
}
继承SQLiteOpenHelper就要实现onCreate和onUpgrade方法。其中,onCreate方法只会调用一次。构造方法有来两个,其中一个包含有4个属性。这里直接在super()方法中把一些属性写死了。
- 第一个属性,context,上下文;
- 第二个属性,DEFAULT_NAME,数据库文件名字以”.db”结尾,这里不是数据库表的名字,要区分。
- 第三个属性,SQLiteDatabase.CursorFactory factory ,我这里设置为了null
- 第四个属性, DEFAULT_VERSION,数据库的版本号,一开始一般默认为版本号为 1
onCreate()方法,用来建立数据库表单。我这里sql语句也很简单,需要注意的是一般以”_id”作为字段名,主键(PRIMARY KEY)为从0开始的整数。
onUpgrade()方法是用来更新数据库表单的。这里的更新是对表的更新。例如添加了字段,删除字段的时候。我这里暂时没有涉及,以后深入了解后,在做补充。
1.3 DBManager
这类个算作是对数据库操作的基本的一些封装。
public class DBManager {
private DBHelper dbHelper;
private SQLiteDatabase database;
public DBManager(Context context) {
dbHelper = new DBHelper(context);
database = dbHelper.getWritableDatabase();
}
public void addPersonInfo(Person person){
database.beginTransaction();//开启事务
try{
database.execSQL("INSERT INTO person VALUES(NULL,?,?)",new Object[]{person.getName(),person.getMoney()});
database.setTransactionSuccessful();//设置事务完成成功
}finally {
database.endTransaction();//设置结束事务
}
}
public boolean deleteByPerson(Person person){
int n = database.delete("person","name = ?",
new String[]{person.getName()});
return n != -1;
}
/**
* 拿到数据库中所有的Person并放入集合中
* @return
*/
public List<Person> getPersonListData(){
List<Person> listData = new ArrayList<>();
Cursor c = getAllPersonInfo();
while (c.moveToNext()){
Person person = new Person();
person.setName(c.getString(c.getColumnIndex("name")));
person.setMoney(c.getString(c.getColumnIndex("money")));
listData.add(person);
}
c.close();
return listData;
}
private Cursor getAllPersonInfo(){
Cursor c = database.rawQuery("SELECT * FROM person", null);
return c;
}
/**
* 关闭 database;
*/
public void closeDB() {
database.close();
}
}
构造方法中需要一个Context,通过context拿到DBHeplper对象dbHelper。dbHelper.getWritableDatabase()拿到SQLiteDatabase对象后,就可以执行sql语句,来实现增删改查。
在getPersonListData()方法中,首先拿到含有全部数据的Cursor。调用curosr.moveToNet()来判断是否还有下一条数据。通过Cursor拿到信息,需要先通过字段得到索引index,然后才能得到内容。
注意需要记得是要记得关闭数据库连接。
数据库部分的内容基本就这些。接下来就是使用RecyclerView将数据库中存储的内容显示出来。
2.使用ItemTouchHelper实现侧滑删除
利用Android v7包中提供的ItemTouchHelper可以实现侧滑,拖拽操作。
public class RVItemTouchHelper extends ItemTouchHelper.Callback {
private static final float ALPHA_FULL = 1.0f;
private ItemTouchHelperAdapter adapter;
private boolean isLongPressDragEnabled = false, isItemViewSwipeEnabled = false;
public RVItemTouchHelper(ItemTouchHelperAdapter adapter) {
this.adapter = adapter;
}
/**
* 支持长按开始拖拽
* @return
*/
public void setLongPressDragEnabled(boolean isLongPressDragEnabled) {
this.isLongPressDragEnabled = isLongPressDragEnabled;
}
@Override
public boolean isLongPressDragEnabled() {
return isLongPressDragEnabled;
}
/**
* 支持左右滑动
*
* @return
*/
public void setItemViewSwipeEnabled(boolean itemViewSwipeEnabled) {
isItemViewSwipeEnabled = itemViewSwipeEnabled;
}
@Override
public boolean isItemViewSwipeEnabled() {
return isItemViewSwipeEnabled;
}
/**
* 持哪个方向的拖拽和滑动
*
* @param recyclerView
* @param viewHolder
* @return
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END;
int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
} else if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
return 0;
}
/**
* 拖拽后调用
*
* @param recyclerView
* @param viewHolder
* @param target
* @return
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
if (viewHolder.getItemViewType() != target.getItemViewType()) {
return false;
}
adapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
/**
* 滑动删除后调用
*
* @param viewHolder
* @param direction
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
adapter.onItemDelete(viewHolder.getAdapterPosition());
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && dX > 200) {//滑动,手指没有离开屏幕
//左右滑动时改变Item的透明度
final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
viewHolder.itemView.setAlpha(alpha);
viewHolder.itemView.setTranslationX(dX);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
继承ItemTouchHelper.Callback后,要实现三个方法。
- getMovementFlags() 这个方法可以设置支持哪个方向的滑动和拖拽
- onMove() 拖拽之后会调用
- onSwiped 滑动后调用
定义一个接口,进行拖拽或者滑动后接口回调
public interface ItemTouchHelperAdapter {
void onItemMove(int formPosition, int toPosition);
void onItemDelete(int position);
}
RecyclerView的Adapter实现ItemTouchHelperAdapter 接口
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.MyViewHolder> implements ItemTouchHelperAdapter{
private List<Person> data = new ArrayList<>();
private Context context;
private DBManager dbManager;
public RVAdapter(Context context) {
this.context = context;
}
public RVAdapter(Context context, DBManager dbManager) {
this.context = context;
this.dbManager = dbManager;
}
public void setData(List<Person> data) {
if (data != null && data.size() > 0){
this.data.clear();
this.data.addAll(data);
notifyDataSetChanged();
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.item_layout,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Person p = data.get(position);
if (p != null){
holder.tv_name.setText(p.getName());
holder.tv_money.setText(p.getMoney());
}
}
@Override
public int getItemCount() {
return data.size();
}
@Override
public void onItemMove(int formPosition, int toPosition) {}
@Override
public void onItemDelete(int position) {
if (dbManager != null){
boolean b = dbManager.deleteByPerson(data.get(position));
if (b){
//删除集合中的对应item的数据
data.remove(position);
//删除RecyclerView中对应item的子View
notifyItemRemoved(position);
}
}
}
class MyViewHolder extends RecyclerView.ViewHolder{
private TextView tv_name,tv_money;
public MyViewHolder(View itemView) {
super(itemView);
tv_name = (TextView) itemView.findViewById(R.id.name_tv_item);
tv_money = (TextView) itemView.findViewById(R.id.money_tv_item);
}
}
}
在Activity中实现ItemTouchHelper与RecyclerView,Adapter的绑定
RVItemTouchHelper callback = new RVItemTouchHelper(adapter);
callback.setItemViewSwipeEnabled(true);//设置可以侧滑
callback.setLongPressDragEnabled(false);//不可以拖拽
ItemTouchHelper rvItemTouchHelper = new ItemTouchHelper(callback);
rvItemTouchHelper.attachToRecyclerView(rv);
3 最后
删除动画效果不好,只是基础的学习过程记录。
代码