使用LitePal做一个收藏新闻的功能 + SwipeBackLayout滑出活动

由于想做一个收藏功能,于是想到了用数据库的方法去实现,顺其自然地我想到了以前看过的《第二行代码》中讲过这方面的知识,后来把书拿出来翻了翻,也去郭神的博客上看了看,收获还是不少滴。

关于LitePal的github地址在这里: https://github.com/LitePalFramework/LitePal

接下来就是怎么去用LitePal了。首先添加依赖:

dependencies {
    compile 'org.litepal.android:core:1.6.0'
}

其次,在app/src/main目录下新建一个assets目录,然后在assets目录中新建一个litepal.xml文件,每次我创建这个文件的时候老跑到value里面去,只好把它拖回到assets中来。

然后就是litepal.xml的内容;

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <dbname value="NewsCollectionStore"></dbname>
    <version value="1"></version>
    <list>
        <mapping class="com.example.administrator.simpleapp.domain.LitePalNewsBean"></mapping>
    </list>
</litepal>

dbname表示想要创建的数据库名字,version是数据库的版本,list中则表示具体的数据类啦。同时,也不能忘了配置LitePalApplication

<manifest>
    <application
        android:name="org.litepal.LitePalApplication"
        ...
    >
        ...
    </application>
</manifest>

还有一点需要注意的是,每个数据类需要继承DataSupport,比如我创建的这个数据库:

public class LitePalNewsBean extends DataSupport {
    private int id;

    private String content;

    private String imageurl;

    private String title;

    private String weburl;

    private String weburl2;

    private String time;

    ...get...
    ...set...
}

上面的id不要忘记了,每在LitePal中添加一个数据,这个id就会自动增加的。

以上,LitePal就算配置完成了,现在只要进行任意一次数据库的操作,数据库就会创建出来。比如,我在MainActivity的Oncreate方法中添加:

        LitePal.getDatabase();

剩下的,关于LitePal的增删改查就不说了,郭神的博客中有详细介绍。

由于我想实现的是给新闻增加收藏和删除的功能,所以主要考虑一下应该怎么去做。

接下来,创建一个LitePal的工具类,作用是

1、判断这条新闻是否已经被添加。

2、收藏一条新闻(添加数据到库)。

3、取消收藏一条新闻(从库中删数据)。

4、查找所有收藏的新闻(查找库中所有数据)

创建DataBaseUtils.class :

public class DataBaseUtils {
    //查询某条新闻是否存在
    public static boolean ifExitInCollect(String title) {
        Boolean flag=false;
        List<LitePalNewsBean> collectNews = DataSupport.select("title").where("title=?", title).find(LitePalNewsBean.class);
        for (LitePalNewsBean collectNews1 : collectNews) {

            if (collectNews1.getTitle() != null) {
                //数据库中存在
                flag=true;
            }
        }
        return flag;
    }

    //查询所有新闻
    public static List<LitePalNewsBean> getCollectNewsList(){
        List<LitePalNewsBean> collectNewses = DataSupport.order("id desc").find(LitePalNewsBean.class);
        return collectNewses;
    }

    //增加一条新闻
    public static void addCollectNews(String content,String imageurl,  String title, 
    String weburl, String weburl2, String time){
        LitePalNewsBean collectNews=new LitePalNewsBean();
        collectNews.setContent(content);
        collectNews.setImageurl(imageurl);
        collectNews.setTitle(title);
        collectNews.setWeburl(weburl);
        collectNews.setWeburl2(weburl2);
        collectNews.setTime(time);
        collectNews.save();
    }

    //删除当前新闻
    public static void deleteCollectNews(String title){
        DataSupport.deleteAll(LitePalNewsBean.class,"title=?",title);
    }
}

接下来就来简单的实验一下,先做一个收藏功能的简陋雏形。

设置新闻列表ListView的长按监听:

    private class MyOnItemLongClickListener implements AdapterView.OnItemLongClickListener{

        private List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen;

        public MyOnItemLongClickListener(List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen) {
            this.listBeen = listBeen;
        }

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            int realPosition = position - 1 + 4;
            String title = listBeen.get(realPosition).getTitle();
            boolean flag = DataBaseUtils.ifExitInCollect(title);
            if (flag){
                Toast.makeText(context, "已经收藏过了", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "收藏成功" , Toast.LENGTH_SHORT).show();
                NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean data = listBeen.get(realPosition);
                DataBaseUtils.addCollectNews(data.getContent(), data.getPic(), data.getTitle(), data.getUrl(), data.getWeburl(), data.getTime());
            }

//            DataSupport.deleteAll(LitePalNewsBean.class);
            List<LitePalNewsBean> allNews = DataSupport.findAll(LitePalNewsBean.class);
            for (LitePalNewsBean theNews : allNews){
                LogUtil.e("" + theNews.getTitle());
//                LogUtil.e("" + theNews.getContent());
//                LogUtil.e("" + theNews.getImageurl());
//                LogUtil.e("" + theNews.getTime());
//                LogUtil.e("" + theNews.getWeburl());
//                LogUtil.e("" + theNews.getWeburl2());
                LogUtil.e("" + theNews.getId());
            }
            return true;
        }
    }

由于上面的打印太多了,所以把其中一些注释掉,然后看一下效果吧:

这里写图片描述

同时看一下打印的日志:

这里写图片描述

上面两张图片的效果也算作是收藏功能的一个雏形吧。接下来就开始着手收藏功能的具体实现吧。

首先准备两张五角星图片,分别表示收藏的两种状态,res/menu中创建collection_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/my_collection"
        android:title="收藏"
        android:icon="@drawable/empty_star"
        app:showAsAction="always"/>
</menu>

在Toolbar中去显示它,Toolbar怎么用就不谈了。

重要的是下面的两个方法中以及其中的逻辑:


    ...
    private boolean flag;
    ...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.collection_menu, menu);
        MenuItem collectionItem = menu.getItem(0);
        flag = DataBaseUtils.ifExitInCollect(title);
        if (flag){ //数据存在,表示已经收藏过了
            collectionItem.setIcon(R.drawable.full_star);
        } else { //数据不存在,没有收藏
            collectionItem.setIcon(R.drawable.empty_star);
        }
        return true;
    }


        public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                finish();
                return true;
            case R.id.my_collection:
                if (flag){ //如果现在处于收藏状态,点击则取消收藏,也就是删除收藏过的新闻
                    DataBaseUtils.deleteCollectNews(title);
                    flag = false;
                    item.setIcon(R.drawable.empty_star);
                    Toast.makeText(this, "取消收藏成功", Toast.LENGTH_SHORT).show();

                    for (LitePalNewsBean theNews : DataBaseUtils.getCollectNewsList()){
                        LogUtil.e("" + theNews.getTitle());
                        LogUtil.e("" + theNews.getId());
                    }
                }else { //如果现在处于未收藏状态,点击则收藏,也就是添加这条没收藏过的新闻
                    DataBaseUtils.addCollectNews(content, imageUrl, title, webUrl, webUrl2, time);
                    flag = true;
                    item.setIcon(R.drawable.full_star);
                    Toast.makeText(this, "收藏成功", Toast.LENGTH_SHORT).show();
                    for (LitePalNewsBean theNews : DataBaseUtils.getCollectNewsList()){
                        LogUtil.e("" + theNews.getTitle());
                        LogUtil.e("" + theNews.getId());
                    }
                }
                break;
            default:break;
        }
        return true;
    }

核心的部分解决了,现在看一下效果:

这里写图片描述

搭配打印日志:

这里写图片描述

效果还是非常明显的,这样,收藏的功能就做好了,之后就是怎么把收藏的数据展示到界面上去了,前面这些都完成了,这个其实很简单的。就不详说了。

看一下收藏效果吧:

这里写图片描述
由于没有对数据库进行监听,所以取消收藏并且退出的时候,列表还没有刷新,这个问题以后再来解决。

接下来顺便做一下左滑退出活动的效果吧。

使用SwipeBackLayout这个控件去实现滑出活动的效果,github的地址是:

https://github.com/ikew0ng/SwipeBackLayout

参考的文章地址是:http://blog.csdn.net/eiuly/article/details/46472783

使用方法可以在上面这盘文章看到,下面是使用步骤:

    1.关联库,我是下载的压缩包关联的库,导入library之后把gradle中一些版本数字改一下即可。

2.让想要使用该效果的活动继承SwipeBackActivity

3.获取SwipeBackLayout的实例:

private SwipeBackLayout swipeBackLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    swipeBackLayout = getSwipeBackLayout();  //获取实例
    swipeBackLayout.setEdgeTrackingEnabled(SwipeBackLayout.EDGE_LEFT);  //设置从左侧滑出活动
    swipeBackLayout.setEdgeSize(DensityUtils.dip2px(NewsDetailActivity.this, 200)); //设置可以滑动的范围,这里使用的是像素转化工具类
    //根据手机的分辨率从 dip 的单位 转成为 px(像素)
    ...
}

下面是工具类DensityUtils:

public class DensityUtils {
    /**
     * 根据手机的分辨率从 dip 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
}

还有一些可加可不加的属性:

在使用的主题中添加下面的属性,否则滑动时activity的下层是黑色的
<item name="android:windowIsTranslucent">true</item>  

当使用BaseActivity时,为了使首页不会滑动删除,只需如下设置即可
setSwipeBackEnable(false); //禁止滑动删除

最后看一下效果:

这里写图片描述

—————————————————————

更新

上面说过,由于没有给数据库添加监听,所以当取消收藏新闻的时候返回到收藏界面,这时候收藏列表是还来不及更新的。

之后试了很多办法还是没有解决,不过后来从一位高人那里得到真传,告知我可以使用广播去更新UI,我试了一下,确实可以!!!

接下来就说明一下是如何做到的。

自定义一个广播,并且要是动态注册的。

在CollectionActivity.class中(也就是收藏列表的界面)添加如下内容:

.
    private IntentFilter filter;
    private MyBroadCastReceiver myBroadCastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        ...

        myBroadCastReceiver = new MyBroadCastReceiver();
        filter = new IntentFilter();
        filter.addAction("com.example.administrator.simpleapp.MY_BROADCAST"); //自定义广播接收值
        registerReceiver(myBroadCastReceiver, filter);

        ...
    }


    class MyBroadCastReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            recyclerView.setAdapter(new MyCollectionRecyclerAdapter(CollectionActivity.this, DataBaseUtils.getCollectNewsList()));
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myBroadCastReceiver);
    }

上面的代码中,addAction的广播值是自定义的。发送广播的时候也需要使用这个值。

还需要注意的是,动态注册的广播一定要及时取消注册,所以在活动的onDestroy中使用了unregisterReceiver方法。

接下来就是在NewsDetailActivity.class(新闻详情界面,就是带收藏键的)中去发送广播了,只需要给收藏按钮的点击事件中添加:

case R.id.my_collection:
                if (flag){ //如果现在处于收藏状态,点击则取消收藏,也就是删除收藏过的新闻
                    DataBaseUtils.deleteCollectNews(title);
                    flag = false;
                    item.setIcon(R.drawable.empty_star);
                    Toast.makeText(this, "取消收藏成功", Toast.LENGTH_SHORT).show();


                    Intent intentFilter = new Intent();
                    intentFilter.setAction("com.example.administrator.simpleapp.MY_BROADCAST");
                    sendBroadcast(intentFilter);


                }else { //如果现在处于未收藏状态,点击则收藏,也就是添加这条没收藏过的新闻
                    DataBaseUtils.addCollectNews(content, imageUrl, title, webUrl, webUrl2, time);
                    flag = true;
                    item.setIcon(R.drawable.full_star);
                    Toast.makeText(this, "收藏成功", Toast.LENGTH_SHORT).show();


                    Intent intentFilter = new Intent();
                    intentFilter.setAction("com.example.administrator.simpleapp.MY_BROADCAST");
                    sendBroadcast(intentFilter);


                }
                break;
            default:break;

来看一下效果吧:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/asjqkkkk/article/details/78503951