android 上划卡住tab_Android Listview多tab上滑悬浮效果

本文介绍了如何在Android应用中实现上滑卡住tab的ListView多tab悬浮效果。通过使用PullToRefreshListView开源库,创建了一个包含两个tab的页面,每个tab都是ListView,公共描述区域作为ListView的头部。在滑动过程中,当tab到达顶部时固定,下拉时恢复。详细步骤包括界面布局、代码实现以及注意事项。

样例

近期要做一个含有两个tab切换页面,两个页面有公共的描述信息区域,两个tab都是listview,可以向上或向下拉动刷新,在页面中部有一个tab切换区域,向上滑动的时候tab区域到顶部后就不在移动,向下拉又重新回到初始位置,先看一样样式图吧!

44b18da7460e03285035a7161ee6d42f.png

整个需求大致如上图所示,其中上拉刷新和下拉刷新没有截图,采用了开源控件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

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@color/white_color" >

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" />

layout="@layout/up_float_tab_layout"

android:visibility="gone" />

tab布局,up_float_tab_layout.xml,text都采用了selector,这样在选中时可以高亮显示

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" >

android:layout_width="fill_parent"

android:layout_height="44dip"

android:minHeight="44dip"

android:orientation="horizontal" >

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" />

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" />

android:layout_width="match_parent"

android:layout_height="@dimen/split_one_pixels"

android:background="@color/color_purple_bd6aff" />

公共部分布局up_float_common_layout.xml

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@color/white_color"

android:orientation="vertical" >

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" />

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" />

接下来就是主页面的代码了

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 item = new ArrayList();

private ArrayList item1 = new ArrayList();

private ArrayList item2 = new ArrayList();

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 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() {

@Override

public void onPullDownToRefresh(PullToRefreshBase refreshView) {

// loadNews();

}

@Override

public void onPullUpToRefresh(PullToRefreshBase 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(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的代码地址,不要错过。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值