首页 > 系统 > Android > 正文

Android-使用LitePal实现一个便笺功能

2019-11-09 17:33:00
字体:
来源:转载
供稿:网友

之前做了个简单的知乎日报的客户端,在这的基础上再加上了便签的功能,使用LitePal操作数据库

效果 这里写图片描述

配置和创建数据库

首先需要添加依赖

compile 'org.litepal.android:core:1.4.1'

在这个功能中还添加了

compile 'com.hanks.animatecheckbox:library:0.1'compile 'com.android.support:multidex:1.0.0'

animatecheckbox:就是一个checkbox,不过好看点。。

multidex:导入第三方项目后,导致重复,添加这个依赖可以进行分包 使用方法http://stackoverflow.com/questions/27377080/after-update-of-as-to-1-0-getting-method-id-not-in-0-0xffff-65536-error-i

需要设置AndroidManifest.xml里的application

android:name="android.support.multidex.MultiDexApplication"

但是问题来了,litePal需要将application设置为

android:name="org.litepal.LitePalApplication"

但是java不能多继承啊..

看了下LitePalFramework/LitePal ,发现可以定义自己的MyApplication

public class MyApplication extends android.support.multidex.MultiDexApplication { @Override public void onCreate() { super.onCreate(); LitePal.initialize(this); }}android:name=".app.MyApplication"

再创建一个assets目录,在目录下建一个litepal.xml

<litepal> <dbname value="oneday"></dbname> <version value="2" /> <list> <mapping class="com.example.linsawako.zhihu.bean.Schedule"/> </list></litepal>

LitePal是对象关系映射的模式,将面向对象的语言和面向关系的数据库之间建立一种映射关系。

<mapping>用来声明要配置的映射模式类,需要完整的类名。 升级数据库的时候,只需要更改version的值。 只需要任意的一次数据库操作,这个数据库就会自动创建出来。

配置的工作就到这。

具体实现

便笺的bean类

public class Schedule extends DataSupport implements Serializable{ PRivate int id; private Date date; private String content; private Boolean finish; public int getId() { return id; } public Date getDate() { return date; } public String getContent() { return content; } public Boolean getFinish() { return finish; } public void setContent(String content) { this.content = content; } public void setDate(Date date) { this.date = date; } public void setFinish(Boolean finish) { this.finish = finish; } public void setId(int id) { this.id = id; }}

模型类需继承DataSupport。implements Serializable是因为需要在使用intent调转时,可以传递整个对象。关于序列化可以看下我的另外一篇文章 java-Serializable 序列化

RecyclerView的Adapter

public class ScheduleAdapter extends RecyclerView.Adapter<ScheduleAdapter.ViewHolder> { public final static int NAME = 1;//用来判断是哪个intent跳转的 private List<Schedule> list; private Context mContext; private int scheduleId; public ScheduleAdapter(List<Schedule> list) { this.list = list; } class ViewHolder extends RecyclerView.ViewHolder { CardView cardView; AnimateCheckBox animateCheckBox; TextView scheduleText; TextView date; public ViewHolder(View itemView) { super(itemView); cardView = (CardView) itemView.findViewById(R.id.schedule_cardview); animateCheckBox = (AnimateCheckBox) itemView.findViewById(R.id.schedule_checkbox); scheduleText = (TextView) itemView.findViewById(R.id.schedule_text); date = (TextView) itemView.findViewById(R.id.schedule_date); } } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (mContext == null) { mContext = parent.getContext(); } View view = LayoutInflater.from(mContext).inflate(R.layout.schedule_item, parent, false); final ViewHolder viewHolder = new ViewHolder(view); //点击后跳转,数据可更改 viewHolder.cardView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int position = viewHolder.getAdapterPosition(); Schedule schedule = list.get(position); Intent intent = new Intent(mContext, AddScheduleActivity.class); intent.putExtra("ActivityName", NAME); intent.putExtra("Content", schedule); mContext.startActivity(intent); } }); //设置checkBox点击后的数据存储 viewHolder.animateCheckBox.setOnCheckedChangeListener(new AnimateCheckBox.OnCheckedChangeListener() { @Override public void onCheckedChanged(View buttonView, boolean isChecked) { int position = viewHolder.getAdapterPosition(); Schedule schedule = list.get(position); schedule.setFinish(viewHolder.animateCheckBox.isChecked()); schedule.update(schedule.getId()); } }); return viewHolder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { Schedule schedule = list.get(position); holder.date.setText(new SimpleDateFormat("yyyy/MM/dd").format(schedule.getDate())); holder.scheduleText.setText(schedule.getContent()); holder.animateCheckBox.setChecked(schedule.getFinish()); } @Override public int getItemCount() { return list.size(); }}

这里涉及了使用LitePal更新数据

Schedule schedule = list.get(position);schedule.setFinish(viewHolder.animateCheckBox.isChecked());schedule.update(schedule.getId());

更新数据的另一个方法,示例

albumToUpdate.updateAll("name = ?", "album");

括号中相当于是where的内容。

ScheduleFragment显示便签的瀑布流

public class ScheduleFragment extends Fragment { private static final String TAG = "ScheduleFragment"; public final static int NAME = 0; private RecyclerView recyclerView; private List<Schedule> scheduleList; private ScheduleAdapter mAdapter; PopOptionUtil mPop;//用于长按时弹出删除提示框 public ScheduleFragment() { } @Override public void onResume() { super.onResume(); scheduleList.clear(); //去掉之前的数据 List<Schedule> newList = DataSupport.order("date desc").find(Schedule.class); scheduleList.addAll(newList);//注意要将数据复制过来,而不是直接使用,不然无法更新数据 mAdapter.notifyDataSetChanged(); Log.d(TAG, "onResume: "); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG, "onCreateView: "); View view = inflater.inflate(R.layout.fragment_schedule, container, false);//fab点击后跳转到添加便签的界面 FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.schedule_fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.d(TAG, "onClick: intent"); Intent intent = new Intent(getContext(), AddScheduleActivity.class); intent.putExtra("ActivityName", NAME); startActivity(intent); } }); mPop = new PopOptionUtil(getContext()); scheduleList = DataSupport.order("date desc").find(Schedule.class); mAdapter = new ScheduleAdapter(scheduleList); recyclerView = (RecyclerView) view.findViewById(R.id.schedule_recyclerview); StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(mAdapter);//设置recyclerview的长按事件 recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { // ... } @Override public void onItemLongClick(View view, final int position) { Log.d(TAG, "onItemLongClick: "); mPop.setOnPopClickEvent(new PopClickEvent() { @Override public void onNextClick() { //删除item Log.d(TAG, "onNextClick: delete"); int id = scheduleList.get(position).getId(); Log.d(TAG, "onNextClick: position:" + position + " id: " + id); deleteData(id); scheduleList.remove(position); mAdapter.notifyItemRemoved(position); mAdapter.notifyItemRangeChanged(0,scheduleList.size());//这个需要设置,因为删除后item的position会改变 mPop.dismiss(); } }); mPop.show(view); } })); return view; }//litepal删除数据 public void deleteData(int id){ DataSupport.deleteAll(Schedule.class, "id = ?", String.valueOf(id)); Log.d(TAG, "deleteData: " + id); }}

关于PopOptionUtil参考了这篇文章仿QQ长按弹出功能菜单 ,就不把具体代码贴上来了

recyclerview的长按事件,参考Android RecyclerView点击事件与长按事件

AddScheduleActivity

public class AddScheduleActivity extends AppCompatActivity { private static final String TAG = "AddScheduleActivity"; private int activityName; private int scheduleID; @Bind(R.id.addSchedule_editText) EditText contentText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_schedule); ButterKnife.bind(this); Toolbar toolbar = (Toolbar) findViewById(R.id.edit_toolbar); setSupportActionBar(toolbar); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true);//让导航按钮显示出来,设置为返回键 } Intent intent = getIntent(); activityName = intent.getIntExtra("ActivityName", 0);//判断是哪个intent跳转的 //修改便签的事件 if (activityName == ScheduleAdapter.NAME){ Schedule schedule = (Schedule) intent.getSerializableExtra("Content"); contentText.setText(schedule.getContent());//填入已有的数据 scheduleID = schedule.getId(); } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home://返回 finish(); break; case R.id.save://存储键 Log.d(TAG, "onOptionsItemSelected: savedata"); if (activityName == ScheduleAdapter.NAME) {//如果是已有的数据就更新,否则存储 updateDate(); } else if (activityName == ScheduleFragment.NAME) { saveDate(); } finish(); break; } return true; } //使用litepal更新数据 public void updateDate() { Schedule schedule = new Schedule(); schedule.setContent(contentText.getText().toString()); schedule.setDate(new Date()); schedule.update(scheduleID); } //使用litepal存储数据 public void saveDate(){ Schedule schedule = new Schedule(); schedule.setDate(new Date());//存入的时间 schedule.setContent(contentText.getText().toString()); schedule.setFinish(false); schedule.save(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_schedule, menu); return true; }}

差不多就这样,GitHub:https://github.com/linsawako/oneDay

说下感想吧,,单单搬砖还是无聊的orz,玩了一寒假,也快开学了,如往常一样,写的计划没一个做到的(:з」∠)…明天起好好打基础


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表