之前做了個簡單的知乎日報的客戶端,在這的基礎上再加上了便簽的功能,使用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,玩了一寒假,也快開學了,如往常一樣,寫的計劃沒一個做到的(:з」∠)…明天起好好打基礎
新聞熱點
疑難解答