如此抄袭Apps之OscHub(二)
来源:互联网 发布:免费书籍阅读软件 编辑:程序博客网 时间:2024/06/05 11:08
在上一篇博客中我们已经实现了OscHub最基本的框架,在接下来的几篇文章中我们来一起逐渐来充实其内容。这篇博客我们主要实现的内容主要有:
- 综合Tab页面的两个Tabs的实现
- 新闻列表数据的解析与展示
话不多说,走起~~~
综合Tab页总共包含了四个子Tabs,这里我们先简单实现资讯和热点两个Tabs列表的展示。在原代码(开源中国Android客户端)中,这两个Tabs均是通过NewsFragment
来展现内容的,而博客与推荐则是用了BlogFragment
实现,这个我下篇文章中会讲到。其实两类列表大同小异,相信聪明的你自己就能猜测到具体的实现方式了。
我们在上一篇博客里已经了解到,综合Tab本身是一个Fragment
实体类,而其所包含的四个子Tabs同样是Fragment
的实体类。这时候我们要注意的是,在添加子Tabs时,使用到的FramgentManager
是通过方法getChildFragmentManager()
得到,而不是调用getFragmentManager
。
与之前的实现方式类似,为了最大可能的共用代码,我们首先实现一个列表Fragment的基类BaseListFragment
。该类是一个抽象类,要求子类必须实现其指定的抽象方法。在该类中实现了展示列表和请求数据的基本框架。类中采取了谷歌官方提供的下拉刷新列表类SwipeRefreshLayout
和自定义的一个交互控件(主要用于数据加载中、数据加载失败、无网络等信息提示)。在该类中,我们暂时不实现加载更多的功能,后面我会用单独的一篇博客来介绍如何使用SwipeRefreshLayout
实现下拉刷新、上拉加载更多的功能。这里我们只要把握整个数据加载、展示的流程就可以了,具体细节大家可以参考原代码了解。
在BaseListFragment
中还提供了数据请求和解析的对外接口和实现方法。数据的请求,我们使用第三方库android-async-http,而数据的解析,则使用了xstream库来解决。这里需要说明的是,使用Gradle来引入xstream时,Android Studio会报异常的错误,所以在工程中我直接使用了原代码中的jar包放入了libs中。
现在就让我们看看BaseListFragment
的基本框架
- 首先是基本的变量声明和依赖注入:
public static final String BUNDLE_KEY_CATALOG = "BUNDLE_KEY_CATALOG"; @Bind(R.id.swiperefreshlayout) protected SwipeRefreshLayout mSwipeRefreshLayout; @Bind(R.id.listview) protected ListView mListView; protected ListBaseAdapter<T> mAdapter; @Bind(R.id.error_layout) protected EmptyLayout mErrorLayout; protected int mCurrentPage = 0; protected int mCatalog = 1; // 错误信息 protected Result mResult; private ParserTask mParserTask;
- 然后是几个关键方法的重写,包括了
onCreate
、getLayoutId
、onCreateView
、onViewCreated
和initView
等方法。 - 在类中,有两个重要的成员变量不得不提,一个是
AsyncHttpResponseHandler
的实例,还一个是其嵌套类ParserTask
的实例:
protected AsyncHttpResponseHandler mHandler = new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBytes) { if (isAdded()) { executeParserTask(responseBytes); } } @Override public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) { } }; class ParserTask extends AsyncTask<Void, Void, String> { private final byte[] reponseData; private List<T> list; public ParserTask(byte[] data) { this.reponseData = data; } @Override protected String doInBackground(Void... params) { try { ListEntity<T> data = parseList(new ByteArrayInputStream( reponseData)); list = data.getList(); } catch (Exception e) { } return null; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); executeOnLoadDataSuccess(list); executeOnLoadFinish(); } }
- 其他几个方法主要是控制
SwipeRefreshLayout
的状态,请大家参照源码来理解。 - 这个类目前提供的唯一抽象方法便是
getListAdapter
。这个很好理解。由于每个子类在显示数据上会略有不同,要求各个子类还实现自己的适配器是很正常的逻辑。即便如此,在原代码中,ListBaseAdapter
还是实现了对刷新列表的控制,子类只需要重写getRealView
方法就可以了。
以上我们简单介绍了列表基类BaseListFragment
的实现,下面我们就来看看如何在子Tabs中使用ViewPager
来展示多个Tabs。
打开我们的BaseViewPagerFragment
类,加入对ViewPager
和Tabs指示器的功能:
protected PagerSlidingTabStrip mTabStrip; protected ViewPager mViewPager; protected ViewPageFragmentAdapter mTabAdapter; protected EmptyLayout mErrorLayout; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.base_viewpage_fragment, null); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); initView(view); } @Override public void initView(View view) { mTabStrip = (PagerSlidingTabStrip) view.findViewById(R.id.pager_tabstrip); mViewPager = (ViewPager) view.findViewById(R.id.pager); mErrorLayout = (EmptyLayout) view.findViewById(R.id.error_layout); mTabAdapter = new ViewPageFragmentAdapter(getChildFragmentManager(), mTabStrip, mViewPager); setScreenPageLimit(); onSetupTabAdapter(mTabAdapter); } protected void setScreenPageLimit() { } protected abstract void onSetupTabAdapter(ViewPageFragmentAdapter adapter);
有了基类BaseViewPagerFragment
的支持,子类的实现就轻而易举了,比如NewsViewPagerFragment
的实现:
public class NewsViewPagerFragment extends BaseViewPagerFragment implements OnTabReselectListener { @Override protected void onSetupTabAdapter(ViewPageFragmentAdapter adapter) { String[] title = getResources().getStringArray( R.array.news_viewpage_arrays); adapter.addTab("news", title[0], NewsFragment.class, getBundle(NewsList.CATALOG_ALL)); adapter.addTab("news_week", title[1], NewsFragment.class, getBundle(NewsList.CATALOG_WEEK)); } private Bundle getBundle(int newType) { Bundle bundle = new Bundle(); bundle.putInt(BaseListFragment.BUNDLE_KEY_CATALOG, newType); return bundle; } @Override protected void setScreenPageLimit() { mViewPager.setOffscreenPageLimit(3); } @Override public void onTabReselect() { try { int currentIndex = mViewPager.getCurrentItem(); Fragment currentFragment = getChildFragmentManager().getFragments() .get(currentIndex); if (currentFragment != null && currentFragment instanceof OnTabReselectListener) { OnTabReselectListener listener = (OnTabReselectListener) currentFragment; listener.onTabReselect(); } } catch (NullPointerException e) { } }}
好了,我们这次的主要内容已经介绍完毕。大家可能觉得介绍的很粗糙。其实,大家看代码就会明白,我们自己在“抄袭”的过程中实际上已经去掉了原代码中我们暂时不关系的东西,而这些留下来的内容便是我们这次需要去学习和掌握的知识。从某种程度上来说,这又何尝不是一种对于原代码的解析呢?
下篇博客中,我们会来学习综合Tab中另外两个Tabs的实现,以及动弹Tab的内容。欢迎大家批评指正。
最后附上效果图:
源码请移步这里
Commit版本:3c20e4
- 如此抄袭Apps之OscHub(二)
- 如此抄袭Apps之OscHub(一)
- 如此抄袭Apps之OscHub(三)
- Mac抄袭施乐PARC图形界面?果真如此?还真是如此啊!
- 抄袭之作,用一下.
- 生命如此之轻
- 经济危机如此之近
- 如此之贱
- iTeXmacs如此之慢
- 《泰囧》如此之火
- 天下如此之大
- 天下如此之大
- 今天如此之忙
- [WebView学习之二]:使用Web Apps 支持不同分辨率屏
- 《Nodejs开发加密货币》之二:Nodejs原来在币圈如此流行?
- 房价为何如此之高
- grep为何如此之快
- 为何编程如此之难?
- Swift入门(七)——结构体(Struct)
- hdu-4348-To the moon-主席树在线区间更新
- 应用限流接入手册
- 微信HTML5页面设计建议
- 问题:浮动影响<a>标签点击?
- 如此抄袭Apps之OscHub(二)
- 没有onFling,找不到onFling()
- 外网访问自己的tomcat
- Java心得5
- dxqdzhiag
- 初体验——使用虚拟机安装mac os
- 2015-08-03
- 设置myeclipse的默认jdk版本(导入jre system library)
- uva 10969