Android频道管理集成

前言

最近开发的项目中有类似网易新闻的频道管理,在完成项目后,我将频道管理单独抽取成Library,方便以后开发,也把总结到的一点知识分享出来。先看看,我的频道管理有什么特点吧。

特点

1.支持固定频道,支持排序,删除。删除,添加皆有动画效果。

2.在排序完成后,通过刷新Adapter而不是重新创建Adapter,性能更好,没有卡顿。

3.使用简单方便,Library中已经封装了数据库操作,获取需要显示的数据只需要一行代码即可

  final List showChannels = dataHelepr.getShowChannels(alldata);

集成

1.添加channellib到你的项目

Android频道管理集成_第1张图片

2.让你的JavaBean实现ChannelEntityCreater接口

import com.trs.channellib.channel.channel.ChannelEntity;

/**
 * Created by zhuguohui on 2016/5/12.
 */
public class MyChannel implements ChannelEntity.ChannelEntityCreater {

   ...
    @Override
    public ChannelEntity createChannelEntity() {
        ChannelEntity entity=new ChannelEntity();
        //是否是固定频道
        entity.setFixed(isFix==1);
        //显示的名称
        entity.setName(title);
        return entity;
    }
}

3.在你的Activity中示例化ChannelDataHelepr,注意ChannelDatahelper需要一个泛型参数,即你用来表示频道的JavaBean

    ChannelDataHelepr dataHelepr;
    dataHelepr = new ChannelDataHelepr(this, this, findViewById(R.id.top_bar));

构造函数声明如下,第一个为上下文,第二个为用来相应频道管理的监听器,第三个为需要将频道管理显示在哪个控件下方。

    public ChannelDataHelepr(@NonNull Context context, @NonNull ChannelDataRefreshListenter channelDataRefreshListenter, @NonNull View showView) 

ChannelDataRefreshListenter 声明

    public static interface ChannelDataRefreshListenter {
        //此方法为刷新数据的方法,只有在频道发生变化的时候才会触发
        public void updateData();
        //此方法为,点击频道中的item时触发,可根据是否有更新选择,ViewPager切换的时机
        public void onChannelSeleted(boolean update, int posisiton);
    }

如我的Activity中这两个方法的实现


    @Override
    public void updateData() {
        loadData();
    }

    @Override
    public void onChannelSeleted(boolean update,final int posisiton) {
        //如果频道没有改变,则立即调整,否则记录下需要调整的position,在数据更新后调整
        if(!update) {
            viewPager.setCurrentItem(posisiton);
        }else {
            needShowPosition=posisiton;
        }
    }


4.设置用于触发频道管理的View

 dataHelepr.setSwitchView(switch_view);

5.在每次数据加载完成后,过滤一遍,只显示订阅的频道。

  private void loadData() {
        new Thread(new Runnable() {
            @Override
            public void run() {

                String data = getFromRaw();
                List alldata = GsonUtil.jsonToBeanList(data, MyChannel.class);
                //过滤数据,如果有新的频道会自动订阅并保存到数据库。
                final List showChannels = dataHelepr.getShowChannels(alldata);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        myChannels.clear();
                        myChannels.addAll(showChannels);
                        adapter.notifyDataSetChanged();
                        if(needShowPosition!=-1){
                            viewPager.setCurrentItem(needShowPosition);
                            needShowPosition=-1;
                        }
                    }
                });

            }
        }).start();
    }

6.为了实现Adapter可以重排序,需要这样实现Adpater,关于原理可以查看我之前的一篇博客ViewPager重排序与更新

public class TitleFragmentAdapter extends FragmentPagerAdapter {
    List channels;
    int id=1;
    Map IdsMap=new HashMap<>();
    List preIds=new ArrayList<>();
    public TitleFragmentAdapter(FragmentManager fm,@NonNull List channels) {
        super(fm);
        this.channels=channels;
    }

    @Override
    public Fragment getItem(int position) {
        SimpleTitleFragment fragment=new SimpleTitleFragment();
        Bundle bundle=new Bundle();
        bundle.putString(SimpleTitleFragment.KEY_TITLE,channels.get(position).getTitle());
        bundle.putString(SimpleTitleFragment.KEY_URL,channels.get(position).getUrl());
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public int getCount() {
        return channels.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return channels.get(position).getTitle();
    }

    @Override
    public long getItemId(int position) {
        return IdsMap.get(getPageTitle(position));
    }

    @Override
    public int getItemPosition(Object object) {
        SimpleTitleFragment fragment= (SimpleTitleFragment) object;
        String title=fragment.getTitle();
        int preId = preIds.indexOf(fragment.getTitle());
        int newId=-1;
        int i=0;
        int size=getCount();
        for(;iif(getPageTitle(i).equals(fragment.getTitle())){
                newId=i;
                break;
            }
        }
        if(newId!=-1&&newId==preId){
            return POSITION_UNCHANGED;
        }
        if(newId!=-1){
            return newId;
        }
        return POSITION_NONE;
    }

    @Override
    public void notifyDataSetChanged() {
        for(MyChannel info:channels){
            if(!IdsMap.containsKey(info.getTitle())){
                IdsMap.put(info.getTitle(),id++);
            }
        }
        super.notifyDataSetChanged();
        preIds.clear();
        int size=getCount();
        for(int i=0;i

关于频道管理控件的实现可以查看这里
使用ItemTouchHelper高效地实现 今日头条 、网易新闻 的频道排序、移动
我在这个控件的基础上,添加了固定频道的功能,需要注意的是,使用这个控件时其父容器必须是FrameLayout否则会出现动画异常的情况。

下载

https://github.com/zhuguohui/ChannelMangerDemo

你可能感兴趣的:(Android)