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

来源:互联网 发布:淘宝代销不赚钱 编辑:程序博客网 时间:2024/06/07 16:49

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

关于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.让想要使用该效果的活动继承SwipeBackActivity3.获取SwipeBackLayout的实例:private SwipeBackLayout swipeBackLayout;@Overrideprotected 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;

来看一下效果吧:

这里写图片描述

原创粉丝点击