Android频道管理集成
2016-05-30 15:43
309 查看
前言
最近开发的项目中有类似网易新闻的频道管理,在完成项目后,我将频道管理单独抽取成Library,方便以后开发,也把总结到的一点知识分享出来。先看看,我的频道管理有什么特点吧。特点
1.支持固定频道,支持排序,删除。删除,添加皆有动画效果。2.在排序完成后,通过刷新Adapter而不是重新创建Adapter,性能更好,没有卡顿。
3.使用简单方便,Library中已经封装了数据库操作,获取需要显示的数据只需要一行代码即可
final List<MyChannel> showChannels = dataHelepr.getShowChannels(alldata);
集成
1.添加channellib到你的项目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<MyChannel> 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<MyChannel> alldata = GsonUtil.jsonToBeanList(data, MyChannel.class); //过滤数据,如果有新的频道会自动订阅并保存到数据库。 final List<MyChannel> 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<MyChannel> channels; int id=1; Map<String,Integer> IdsMap=new HashMap<>(); List<String> preIds=new ArrayList<>(); public TitleFragmentAdapter(FragmentManager fm,@NonNull List<MyChannel> 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(;i<size;i++){ if(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<size;i++){ preIds.add((String) getPageTitle(i)); } } }
关于频道管理控件的实现可以查看这里
使用ItemTouchHelper高效地实现 今日头条 、网易新闻 的频道排序、移动
我在这个控件的基础上,添加了固定频道的功能,需要注意的是,使用这个控件时其父容器必须是FrameLayout否则会出现动画异常的情况。
下载
https://github.com/zhuguohui/ChannelMangerDemo相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件