亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > 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,玩了一寒假,也快開學了,如往常一樣,寫的計劃沒一個做到的(:з」∠)…明天起好好打基礎


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品视频色| 亚州成人av在线| 久久免费视频在线| 久久国产精品影视| 日韩免费观看av| 91精品国产91久久久久久吃药| 亚洲一区二区自拍| 97人人模人人爽人人喊中文字| 国产精品啪视频| 欧美精品在线看| 精品中文字幕久久久久久| 色偷偷88888欧美精品久久久| www.欧美三级电影.com| 久久频这里精品99香蕉| 亚洲一区二区三区在线免费观看| 欧美久久精品午夜青青大伊人| 亚洲国产成人久久综合| 国产精品观看在线亚洲人成网| 亚洲欧洲午夜一线一品| 高清欧美电影在线| 亚洲国产欧美一区二区三区同亚洲| 操人视频在线观看欧美| 久久国产精品亚洲| 伊人一区二区三区久久精品| 亚洲色图色老头| 亚洲精品电影网| 欧美网站在线观看| 久久久女人电视剧免费播放下载| 亚洲一区二区少妇| 日韩精品极品在线观看播放免费视频| 色中色综合影院手机版在线观看| 亚洲午夜激情免费视频| 成人淫片在线看| 欧美放荡办公室videos4k| 亚洲欧美日韩精品久久| 欧美激情欧美激情| 欧美裸体xxxx极品少妇软件| 一本一本久久a久久精品综合小说| 97久久超碰福利国产精品…| 欧美日韩美女在线观看| 日韩在线免费观看视频| 人人爽久久涩噜噜噜网站| 亚洲国产另类久久精品| 欧美日韩在线观看视频小说| 浅井舞香一区二区| 成人国产精品免费视频| 亚洲一区二区三区sesese| 成人在线一区二区| 久久久国产精品一区| 亚洲欧美资源在线| 欧洲中文字幕国产精品| 欧美一区在线直播| 日韩一级裸体免费视频| 日韩av一区二区在线观看| 日韩av在线免播放器| 国外成人在线视频| 国产精品video| 久久99久久99精品免观看粉嫩| 久久精品国产欧美激情| 精品美女久久久久久免费| 亚洲国产高清福利视频| 在线一区二区日韩| 久久久久久久久久久久久久久久久久av| 欧美激情亚洲另类| 中文字幕久久亚洲| 久久精品99国产精品酒店日本| 国产精品久久久久久久久久新婚| 91精品久久久久久综合乱菊| 91国语精品自产拍在线观看性色| 91香蕉嫩草影院入口| 中文字幕v亚洲ⅴv天堂| 亚洲黄页网在线观看| 91伊人影院在线播放| 欧美日韩国内自拍| 亚洲免费av片| 久热精品视频在线免费观看| 色婷婷av一区二区三区在线观看| 97精品久久久| 国语自产精品视频在线看一大j8| 国产视频亚洲精品| 91伊人影院在线播放| 一区二区三区视频免费在线观看| 亚洲精品久久久久中文字幕欢迎你| 久久久久久久亚洲精品| 欧美黑人一区二区三区| 欧美日韩在线影院| 欧美日韩国产精品| 国产高清在线不卡| 亚洲美女av电影| 亚洲国产日韩欧美综合久久| 成人激情综合网| 成人乱色短篇合集| 国产日韩欧美在线| 成人网中文字幕| 精品中文字幕在线2019| 成人免费看片视频| 亚洲中国色老太| 亚洲第一在线视频| 这里只有精品丝袜| 亚洲乱亚洲乱妇无码| 成人免费在线网址| 国产一区二区三区在线| 欧美一区二区三区免费观看| 国产精品一区二区三区免费视频| 国产精品美女午夜av| 久久精品成人欧美大片古装| 亚洲老司机av| 精品视频久久久久久| 国产精品成人免费视频| 亚洲男人天天操| 国产欧美日韩精品丝袜高跟鞋| 欧美日韩国产精品一区二区不卡中文| 亚洲欧美另类在线观看| 三级精品视频久久久久| 精品视频中文字幕| 日韩网站免费观看| 91久久久久久久久久久| 国产91ⅴ在线精品免费观看| 国产成人精品在线| 久久91亚洲精品中文字幕| 国产综合香蕉五月婷在线| 欧美亚洲视频在线观看| 亚洲天堂av综合网| 欧美高跟鞋交xxxxhd| 日韩精品欧美国产精品忘忧草| 久久成人亚洲精品| 亚洲在线观看视频| 九九热这里只有在线精品视| 欧美高清视频在线| 蜜臀久久99精品久久久久久宅男| 国产精品久久久久不卡| 日韩有码在线观看| 亚洲免费视频在线观看| 日韩二区三区在线| 日韩美女在线播放| 久久成人精品视频| 91国自产精品中文字幕亚洲| 一夜七次郎国产精品亚洲| 亚洲精品丝袜日韩| 日韩欧美在线第一页| 国产精品自产拍在线观看| 国产欧美日韩免费| 色妞久久福利网| 国产精品免费视频久久久| 疯狂蹂躏欧美一区二区精品| 亚洲免费视频网站| 日韩美女视频免费看| 久久久99久久精品女同性| 欧美性猛交xxxxx免费看| 青青草精品毛片| 92裸体在线视频网站| 欧洲成人免费aa| 国产成人一区二| 中文日韩在线观看| 在线成人免费网站| 久久久久国产精品免费| 国产成人福利夜色影视| 热久久99这里有精品| 国内精品小视频在线观看| 精品国产乱码久久久久久婷婷| 日韩欧美在线观看视频| 日韩精品在线视频| 国产精品永久在线| 久久国产精品亚洲|