整个需求大致如上图所示,其中上拉刷新和下拉刷新没有截图,采用了开源控件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.PullToRefreshListViewxmlns: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" /><includelayout="@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" ><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="44dip"android:minHeight="44dip"android:orientation="horizontal" ><TextViewandroid: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" /><TextViewandroid: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><Viewandroid: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" ><ImageViewandroid: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" /><TextViewandroid: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 style="@style/horizontal_gray_divider" /><View style="@style/horizontal_gray_divider" /></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;@Overrideprotected 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>() {@Overridepublic void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {// loadNews();}@Overridepublic void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {// loadOlds();}});listView.setOnScrollListener(new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {if (firstVisibleItem < 2) {// 悬浮tab出现时机,listview含有三个headertitleFloatTab.setVisibility(View.GONE);} elsetitleFloatTab.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);}@Overridepublic 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 tab1tab2Pos = 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 tab2tab1Pos = 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() {@Overridepublic void run() {listView.getRefreshableView().setSelectionFromTop(tab1Pos, tab1OffsetY);}});} else {listView.post(new Runnable() {@Overridepublic void run() {listView.getRefreshableView().setSelectionFromTop(tab2Pos, tab2OffsetY);}});}}}总结: