[安卓]新闻客户端(四) 主页面之slidingMenu & fragment(2)
来源:互联网 发布:java 编码url 空格 20 编辑:程序博客网 时间:2024/04/30 00:46
继上篇,要实现点击侧边栏的标题,新闻页随之变动,实际的原理是侧边栏的四个listener被点击后,通过mActivity找到contentFragment,再找到其下的viewpager,然后找到相应的framelayout,去replace。
具体来说,要在侧边栏响应,listener,其中要根据选中的标题,来显示具体的新闻页,setCurrentMenuDetailPager(position),这个方法在初始化数据中调用;
这个方法内,要先通过mainActivity获得mActivity,再通过这个mActivity去调用mainActivity的getContentFragment方法,再调用到contentFragment中的getNewsCenterPager方法找到具体的newspager,再去调用他的setCurrentMenuDetailPager来完成页面的显示
侧边栏中
public void initData() {// 初始化数据,点击事件,同时点击后填充数据,adaptersuper.initData();lv_left_menu.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {// TODO Auto-generated method stubmCurrentPos = position;menulistadapter.notifyDataSetChanged();//点击侧边栏改变新闻页的内容setCurrentMenuDetailPager(position);}});}private void setCurrentMenuDetailPager(int position) {// TODO Auto-generated method stubMainActivity MainUI = (MainActivity) mActivity;MainUI.getContentFragment().getNewsCenterPager().setCurrentMenuDetailPager(position);}
主页中
// 获取主页面fragmentpublic ContentFragment getContentFragment() {FragmentManager fm = getSupportFragmentManager();ContentFragment fragment = (ContentFragment) fm.findFragmentByTag(FRAGMENT_CONTENT);return fragment;}
ContentFragment中
public NewsCenterPager getNewsCenterPager(){return (NewsCenterPager) mPagerList.get(1);}
最后,NewsCenterPager中,注意,他是挂在帧布局中的,所以最好清除之前的布局,否则可能有重叠现象;然后找到mPagers这个list,装4个新闻子内容,根据位置信息来添加
//响应侧边栏的点击事件,显示具体的内容public void setCurrentMenuDetailPager(int position) {//在这个pager里面的flcontent(帧布局)里面增加一个布局 BaseMenuDetailPager baseMenuDetailPager = mPagers.get(position); flContent.removeAllViews();// 清除之前的布局 flContent.addView( baseMenuDetailPager.mRootView); baseMenuDetailPager.initData();// 初始化当前页面的数据 toggleSlidingMenu();}
这样,就能完成点击侧边栏改变新闻页内容的功能
再来实现侧边栏的新闻版块,首先我们需要一个view用来填充,之前直接用的text,这里应该有一个布局,上面一栏有一个viewPagerIndicator,viewpager里的标题栏,这个需要导包,再加上一个imagebutton,点击后来显示更多功能键,组成一个水平布局;同时,下面应该是一整个的viewpager,可以滑动,这里由于功能需求,也是写了一个类继承viewpager,后面再说
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <com.viewpagerindicator.TabPageIndicator android:id="@+id/indicator" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1"/> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:layout_gravity="center_vertical" android:background="@android:color/transparent" android:src="@drawable/news_cate_arr" android:id="@+id/ib_newsmenudetail_arrow"/> </LinearLayout> <com.example.mynewsapp.view.CanScrollViewPager android:id="@+id/vp_menu_detail" android:layout_width="match_parent" android:layout_height="match_parent"/></LinearLayout>
此时服务器端的数据更多了,有层次关系,children,新闻里分各种新闻,NewsMenuDetailPager里除了继承Base的构造方法外,还需要一个新的构造方法,参数里应该带上更多数据,同时,在NewsCenterPager里,填充的时候,响应的代码也应该变化
public class NewsMenuDetailPager extends BaseMenuDetailPager{private ArrayList<NewsTabData> tabdata;public NewsMenuDetailPager(Activity activity) {super(activity);// TODO Auto-generated constructor stub}public NewsMenuDetailPager(Activity mActivity,ArrayList<NewsTabData> children) {// TODO Auto-generated constructor stubsuper(mActivity);tabdata = children;}
// 准备4个菜单详情页mPagers = new ArrayList<BaseMenuDetailPager>();/*mPagers.add(new NewsMenuDetailPager(mActivity));*/mPagers.add(new NewsMenuDetailPager(mActivity,mNewsData.data.get(0).children));
对于这个children,是一个复杂布局,所以需要一个新的类来装他,TabDetailPager,其实装的就是mRootView,同时需要一个布局,list
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:cacheColorHint="#FFF" android:id="@+id/lv_tab_detail_news"/></LinearLayout>
来看这个布局
首先是viewpager,他需要adapter,在初始化数据时调用,他的数据来自于解析服务器端
看其封装的数据,children下就是新闻子栏目标题,12个,而children在一开始,点击新闻中心这个button时就已经解析到了,所以直接传到adapter就好
所以这里adapter内,如前文所说,要另一个构造函数,参数带的children,在其内,拿到children,并将数据给一个arraylist,这样也无需自己去联网解析
然后填充viewpager时,又需要一个装满view的list,每次在adapter内初始化一个item时,根据position回传一个view,所以在填数据之前,要先把这个装view的list装满
adapter内的几个方法,都是要根据TabDetailPager来做相关操作
初始化item是,把tablist里的东西拿出来封装成一个类,再用这个类的mRootView来初始化item,这个流程就是搞一个list,再把它填满,在把他里面的rootview拿出来给item初始化
然后这时候view里还需要数据,顺便初始化一下,初始化的方法在TabDetailPager内,这里调用即可,也就是那边弄得什么数据,这边就显示什么数据
这里indicator需要导第三方库,可以根据需求修改源码,而不是直接导封装好的jar包。之前倒库的时候又同名的,这里先在外面把这个库的名字改了再放到workspace里
public class NewsMenuDetailPager extends BaseMenuDetailPager{private ArrayList<NewsTabData> tabdata;private ViewPager vp_menu_newsdetail;private ArrayList<TabDetailPager> tabList ;private TabPageIndicator indicator;private ImageButton ib_newsmenudetail_arrow;public NewsMenuDetailPager(Activity activity) {super(activity);// TODO Auto-generated constructor stub}public NewsMenuDetailPager(Activity mActivity,ArrayList<NewsTabData> children) {// TODO Auto-generated constructor stubsuper(mActivity);tabdata = children;}@Overridepublic View initViews() {View view = View.inflate(mActivity, R.layout.news_menu_detail, null); vp_menu_newsdetail = (ViewPager) view.findViewById(R.id.vp_menu_detail); indicator = (TabPageIndicator)view.findViewById(R.id.indicator); //indicator.setViewPager(vp_menu_newsdetail);这里写会报错,因为initView的时候 adapter还没有 ib_newsmenudetail_arrow = (ImageButton) view.findViewById(R.id.ib_newsmenudetail_arrow); ib_newsmenudetail_arrow.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint currentItem = vp_menu_newsdetail.getCurrentItem();vp_menu_newsdetail.setCurrentItem(++currentItem, false);}}); return view;}@Overridepublic void initData() {// TODO Auto-generated method stubsuper.initData(); tabList = new ArrayList<TabDetailPager>();for (int i =0;i<tabdata.size();i++){tabList.add(new TabDetailPager(mActivity,tabdata.get(i)));}//给detial页面中的viewpager 设置数据 vp_menu_newsdetail.setAdapter(new MenuDetialVpAdapter()); indicator.setViewPager(vp_menu_newsdetail); }class MenuDetialVpAdapter extends PagerAdapter{@Overridepublic int getCount() {// TODO Auto-generated method stubreturn tabList.size();}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {// TODO Auto-generated method stubreturn arg0==arg1;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {TabDetailPager tabDetailPager = tabList.get(position);container.addView(tabDetailPager.mRootView);tabDetailPager.initData();return tabList.get(position).mRootView;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {// TODO Auto-generated method stub container.removeView(tabList.get(position).mRootView);}@Overridepublic CharSequence getPageTitle(int position) { return tabdata.get(position).title;}}}
另外,仅仅导入了indicator还是不够的,虽然小标题栏能滑动,但是没有文本显示标题,需要重写title,也是从children中拿的,如上代码所示
然后调整格式
这里导入的库再引用的,直接在库的文件里看styles,然后要改什么属性,就直接点进去改,这是原来的
这里主要也是背景和文字在点击时的颜色变动,给了一个selector,比如背景,没选中时时透明色,选中了给一个图标,字体选中时红色,未选中时黑色
修改后
还有此时背景黑色,可以去项目的main里面改成白色
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFF" android:id="@+id/fl_content"></FrameLayout>
然后manifest里应该注册theme
<activity android:name=".MainActivity" android:theme="@style/Theme.PageIndicatorDefaults"> </activity>
还有一个button,不能在布局里写个onclick属性,然后再写个方法来启用这个listener,因为这个类是一个单纯的类,系统不调用他,所以应该通过setOnClickListener来注册他
ib_newsmenudetail_arrow.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint currentItem = vp_menu_newsdetail.getCurrentItem();//当前的获取到,加一个就是滑动后的下一个,false代表中间不要过渡动画vp_menu_newsdetail.setCurrentItem(++currentItem, false);}});
然后还有个bug,点击侧边栏的新闻后,在新闻页里左右滑动,总是会自动脱拖出标题栏,往左滑的时候,画面也不正常,这是由于安卓touch机制引起的,所以前面的viewpager是继承写的,然后这里要处理ontouch事件,同前面的类似,而且这里还有一个问题,在第一个页面的时候就不能往左拖了,在这里改一下,需要做一个判断,让他的父控件能处理,才能给到activity,再给到leftmenu,第0个item还是让父控件处理
public class CanScrollViewPager extends ViewPager{public CanScrollViewPager(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public CanScrollViewPager(Context context) {super(context);// TODO Auto-generated constructor stub}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if (getCurrentItem() != 0) {getParent().requestDisallowInterceptTouchEvent(true);// 用getParent去请求,不拦截} else {// 如果是第一个页面,需要显示侧边栏, 请求父控件拦截getParent().requestDisallowInterceptTouchEvent(false);// 拦截}return super.dispatchTouchEvent(ev);}}
然后要完善tabDetailMenu,他是一个复杂布局,用来显示具体内容的,内部是一个viewpager和list,看具体的服务器端的数据,里面具体的内容是给了一个URL,指向一些文件
URL对应的文件夹下,也有一个JSON数据
topnews下有4个资源,对应着页面里横向的viewpager
另外news下由10条新闻,对应着list里的数据
这个数据的解析,实际上在点击侧边栏新闻后,newsmenu里要获取到这个数据,adapter里要填充,调用的tabmenudetail初始化数据方法,要在其中去解析数据
想要解析这些数据,则需要在父亲初始化tabmenu时,把数据传进来,也就是需要新的构造函数
解析依然用的xutils,很简单
- [安卓]新闻客户端(四) 主页面之slidingMenu & fragment(2)
- [安卓]新闻客户端(三) 主页面之slidingMenu & fragment(1)
- [安卓]新闻客户端(五) 主页面之slidingMenu & fragment(3)
- [安卓]新闻客户端(六) 主页面之slidingMenu & fragment(4)
- JSP新闻系统之四后台主页面
- 安卓开发之简易新闻客户端
- 安卓新闻客户端
- 黑马北京新闻项目连载(2)--->侧滑菜单栏、主页面Fragment搭建
- 安卓新闻客户端(四)ViewPager使用
- 安卓基础笔记5之新闻客户端--OKHttp查询
- 安卓之旅第十一站--简易新闻客户端
- 模拟实现网易新闻客户端主界面(侧滑SlidingMenu+ViewPager+Fragment)
- 模拟实现网易新闻客户端主界面(侧滑SlidingMenu+ViewPager+Fragment)
- 模拟实现网易新闻客户端主界面(侧滑SlidingMenu+ViewPager+Fragment)
- 安卓之动画主页
- 实现安卓主页面代码
- android小项目之新闻客户端四
- 安卓碎片fragment菜单侧滑slidingmenu
- 排序算法!~
- BaseExpandableListAdapter的用法
- 黑马程序员————第十八天
- 【MapReduce】常用计算模型详解
- qt 正则表达式
- [安卓]新闻客户端(四) 主页面之slidingMenu & fragment(2)
- Android 自定义View 之 format 详解
- android4.4.+状态栏改变颜色
- UGUI 实现界面 渐隐渐现 FadeIn/Out 效果
- 黑马程序员——Java基础---GUi(第22天)
- LPC17xx的MCPWM周期设置与计算
- 被AppStore拒绝理由(一)
- 观念的水位
- Algorithms—41.First Missing Positive