样例
近期要做一个含有两个tab切换页面,两个页面有公共的描述信息区域,两个tab都是ListvIEw,可以向上或向下拉动刷新,在页面中部有一个tab切换区域,向上滑动的时候tab区域到顶部后就不在移动,向下拉又重新回到初始位置,先看一样样式图吧!
整个需求大致如上图所示,其中上拉刷新和下拉刷新没有截图,采用了开源控件PullToRefreshListVIEw来实现这个效果。
实现方式
总体思路,为了简单不想监控很多手势问题,因此投机取巧的采用下面的方式来实现,
a. 整个页面是一个ListvIEw,公共的区域作为ListvIEw的header添加进来,两个切换的tab也作为一个header加入,
b. 在页面布局的时候在ListvIEw上面添加一层,里面放tab的布局,这个tab的布局与ListvIEw的header中的是同一个布局,
c. 之后当ListvIEw滑动时候在onScroll函数中处理页面tab布局的显示与隐藏,当ListvIEw的tab布局到达屏幕顶部时,显示页面中的tab布局,向下滑动当整个tab都出现是影藏界面中的tab布局
d. tab切换,由于tab1,tab2的数据不同,因此采用了三个数据源,在tab切换的时候,数据来回切换,当点击tab时,记住当前显示的tab的pos和偏移量(只记住pos重定位的时候会有偏差)
demo的大致流程就是这样了,没有添加刷新的处理,虽然实际项目中时处理了更多的逻辑,但是demo不想写太复杂(主要是没有人看,就自己看,稍稍写写)。
说了这么多,可能看的人的还是不怎么明白,下面就来看代码吧
首先是界面布局,底层一个ListvIEw,顶部一个tab布局,界面布局up_float_first_activity.xml
<?xml version="1.0" enCoding="utf-8"?><FrameLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:background="@color/white_color" > <com.example.toolBox.upfloat.PullToRefreshListVIEw xmlns:ptr="http://schemas.androID.com/apk/res-auto" androID:ID="@+ID/up_float_ListvIEw" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:cachecolorHint="@color/white_color" androID:divIDer="@color/transpant" androID:divIDerHeight="0dip" androID:fadingEdge="none" androID:fastScrollEnabled="false" androID:ListSelector="@color/transpant" androID:smoothScrollbar="true" androID:visibility="visible" ptr:ptrheaderTextcolor="@color/color_333333" ptr:ptrMode="both" /> <include layout="@layout/up_float_tab_layout" androID:visibility="gone" /></FrameLayout>
tab布局,up_float_tab_layout.xml,text都采用了selector,这样在选中时可以高亮显示
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:ID="@+ID/up_float_tab_root" androID:layout_wIDth="fill_parent" androID:layout_height="wrap_content" androID:background="@color/white_color" androID:minHeight="44dip" androID:orIEntation="vertical" > <linearLayout androID:layout_wIDth="fill_parent" androID:layout_height="44dip" androID:minHeight="44dip" androID:orIEntation="horizontal" > <TextVIEw androID:ID="@+ID/up_fload_tab1" androID:layout_wIDth="0dip" androID:layout_height="match_parent" androID:layout_weight="1" androID:background="@drawable/show_event_detail_tab_selector" androID:gravity="center" androID:text="@string/up_float_tab1" androID:textcolor="@color/show_event_detail_tab_text_selector" androID:textSize="17sp" /> <TextVIEw androID:ID="@+ID/up_float_tab2" androID:layout_wIDth="0dip" androID:layout_height="match_parent" androID:layout_weight="1" androID:background="@drawable/show_event_detail_tab_selector" androID:gravity="center" androID:text="@string/up_float_tab2" androID:textcolor="@color/show_event_detail_tab_text_selector" androID:textSize="17sp" /> </linearLayout> <VIEw androID:layout_wIDth="match_parent" androID:layout_height="@dimen/split_one_pixels" androID:background="@color/color_purple_bd6aff" /></linearLayout>
公共部分布局up_float_common_layout.xml
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="fill_parent" androID:layout_height="wrap_content" androID:background="@color/white_color" androID:orIEntation="vertical" > <ImageVIEw androID:ID="@+ID/show_event_detail_bg" androID:layout_wIDth="fill_parent" androID:layout_height="125dip" androID:contentDescription="@string/empty" androID:scaleType="fitXY" androID:src="@drawable/pic1" /> <TextVIEw androID:ID="@+ID/show_event_detail_desc" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_marginBottom="24dip" androID:layout_marginleft="15dip" androID:layout_marginRight="15dip" androID:layout_margintop="24dip" androID:text="@string/up_float_desc" androID:textcolor="@color/color_black_333333" androID:textSize="14sp" /> <VIEw /> <VIEw /></linearLayout>
接下来就是主页面的代码了
package com.example.toolBox.upfloat.activity;import java.util.ArrayList;import androID.os.Bundle;import androID.support.v7.app.ActionBaractivity;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEw.OnClickListener;import androID.Widget.AbsListVIEw;import androID.Widget.AbsListVIEw.OnScrollListener;import androID.Widget.ArrayAdapter;import androID.Widget.linearLayout;import androID.Widget.ListVIEw;import androID.Widget.TextVIEw;import com.example.toolBox.R;import com.example.toolBox.upfloat.PullToRefreshBase;import com.example.toolBox.upfloat.PullToRefreshBase.OnRefreshListener2;import com.example.toolBox.upfloat.PullToRefreshListVIEw;/** * * * @author sunyoujun * */public class UpfloatFirstActivity extends ActionBaractivity implements OnClickListener { public static final int TYPE_TAB_1 = 1; public static final int TYPE_TBA_2 = 2; private int tab2Pos = 0; private int tab2OffsetY = 0; private int tab1Pos = 0; private int tab1OffsetY = 0; private ArrayList<String> item = new ArrayList<String>(); private ArrayList<String> item1 = new ArrayList<String>(); private ArrayList<String> item2 = new ArrayList<String>(); protected PullToRefreshListVIEw ListVIEw; private linearLayout TitleVIEw; private LayoutInflater infater; private linearLayout TitleTab; private linearLayout TitlefloatTab; private TextVIEw latestTv; private TextVIEw latestfloatTv; private TextVIEw hottv; private TextVIEw hotfloatTv; private int currentType = TYPE_TAB_1; private ArrayAdapter<String> adapter; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.up_float_first_activity); findVIEws(); setVIEwsListener(); updateTabSelectState(); initData(); initListVIEw(); } private voID findVIEws() { ListVIEw = (PullToRefreshListVIEw) findVIEwByID(R.ID.up_float_ListvIEw); TitlefloatTab = (linearLayout) findVIEwByID(R.ID.up_float_tab_root); latestfloatTv = (TextVIEw) TitlefloatTab.findVIEwByID(R.ID.up_float_tab2); hotfloatTv = (TextVIEw) TitlefloatTab.findVIEwByID(R.ID.up_fload_tab1); infater = LayoutInflater.from(this); TitleVIEw = (linearLayout) infater.inflate(R.layout.up_float_common_layout,null); TitleTab = (linearLayout) infater.inflate(R.layout.up_float_tab_layout,null); latestTv = (TextVIEw) TitleTab.findVIEwByID(R.ID.up_float_tab2); hottv = (TextVIEw) TitleTab.findVIEwByID(R.ID.up_fload_tab1); } private voID setVIEwsListener() { latestTv.setonClickListener(this); hottv.setonClickListener(this); latestfloatTv.setonClickListener(this); hotfloatTv.setonClickListener(this); updateTabSelectState(); } /** * 更新tab栏选中状态 */ private voID updateTabSelectState() { boolean isTab1 = (currentType == TYPE_TAB_1); hottv.setSelected(isTab1); hotfloatTv.setSelected(isTab1); latestTv.setSelected(!isTab1); latestfloatTv.setSelected(!isTab1); } private voID initData() { for (int i = 1; i <= 50; i++) { item1.add("tab1-- item ---" + i); item2.add("tab2-- item ---" + i); } } private voID initListVIEw() { setListVIEwListener(); ListVIEwAddheader(); ListVIEwLoadData(); } private voID setListVIEwListener() { ListVIEw.setonRefreshListener(new OnRefreshListener2<ListVIEw>() { @OverrIDe public voID onPullDownToRefresh(PullToRefreshBase<ListVIEw> refreshVIEw) { // loadNews(); } @OverrIDe public voID onPullUpToRefresh(PullToRefreshBase<ListVIEw> refreshVIEw) { // loadolds(); } }); ListVIEw.setonScrollListener(new OnScrollListener() { @OverrIDe public voID onScrollStateChanged(AbsListVIEw vIEw,int scrollState) { } @OverrIDe public voID onScroll(AbsListVIEw vIEw,int firstVisibleItem,int visibleItemCount,int totalitemCount) { if (firstVisibleItem < 2) {// 悬浮tab出现时机,ListvIEw含有三个header TitlefloatTab.setVisibility(VIEw.GONE); } else TitlefloatTab.setVisibility(VIEw.VISIBLE); ; } }); } private voID ListVIEwAddheader() { ListVIEw.getRefreshableVIEw().addheaderVIEw(TitleVIEw); ListVIEw.getRefreshableVIEw().addheaderVIEw(TitleTab); } protected voID ListVIEwLoadData() { item.clear(); item.addAll(item1); adapter = new ArrayAdapter<String>(this,R.layout.List_item,androID.R.ID.text1,item); ListVIEw.setAdapter(adapter); } @OverrIDe public voID onClick(VIEw v) { switch (v.getID()) { case R.ID.up_fload_tab1: switchTabtList(true); break; case R.ID.up_float_tab2: switchTabtList(false); break; default: break; } } private voID switchTabtList(boolean isTab1) { if (isTab1) { if (currentType == TYPE_TAB_1) { return;// 说明点击的是相同的活动列表,不用改变 } else {// tab2 switch tab1 tab2Pos = ListVIEw.getRefreshableVIEw().getFirstVisibleposition(); tab2OffsetY = getoffsetY(); currentType = TYPE_TAB_1; item2.clear(); item2.addAll(item); item.clear(); item.addAll(item1); } } else { if (currentType == TYPE_TBA_2) { return; } else {// tab1 switch tab2 tab1Pos = ListVIEw.getRefreshableVIEw().getFirstVisibleposition(); tab1OffsetY = getoffsetY(); currentType = TYPE_TBA_2; item1.clear(); item1.addAll(item); item.clear(); item.addAll(item2); } } updateTabSelectState(); relocationLastPos(); } private int getoffsetY(){ VIEw vIEw = ListVIEw.getRefreshableVIEw().getChildAt(0); return vIEw != null ? vIEw.gettop() : 0; } /** * 重新定位到上次的位置 */ private voID relocationLastPos() { if (adapter != null) { adapter.notifyDataSetChanged(); } if (currentType == TYPE_TAB_1) { ListVIEw.post(new Runnable() { @OverrIDe public voID run() { ListVIEw.getRefreshableVIEw().setSelectionFromtop(tab1Pos,tab1OffsetY); } }); } else { ListVIEw.post(new Runnable() { @OverrIDe public voID run() { ListVIEw.getRefreshableVIEw().setSelectionFromtop(tab2Pos,tab2OffsetY); } }); } }}
总结:
a 上面的demo只是实现了向上滑动的效果,其实有很大的局限性,两个tab的item布局要一致,才能自由切换,其次是两个tab不能左右滑动
b 上面的只适合两个或者一个tab,再多要控制的变量状态就更多,很容易出错,并且上面还没有包含刷新的效果,数据返回时不能仅仅是添加到item,而要判断刷新tab与当前显示tab的关系。
c 看了其他的开源项目,之后如果有时间会写一个demo,做真正的多个tab,并且能左右切换的效果。
ps: 鉴于还是有很多人要源代码,我就在下一篇重新实现了现有的方式,并且附上了git的代码地址,不要错过。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android Listview多tab上滑悬浮效果全部内容,希望文章能够帮你解决Android Listview多tab上滑悬浮效果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)