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

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

效果
这里写图片描述

配置和创建数据库

首先需要添加依赖

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

在这个功能中还添加了

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

需要设置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,玩了一寒假,也快开学了,如往常一样,写的计划没一个做到的(:з」∠)…明天起好好打基础

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值