首页 Java java教程 Android Listview上下拉动刷新tab滑动切换功能

Android Listview上下拉动刷新tab滑动切换功能

Jan 13, 2017 am 11:40 AM

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

Android Listview上下拉动刷新tab滑动切换功能

整个需求大致如上图所示,其中上拉刷新和下拉刷新没有截图,采用了开源控件PullToRefreshListView来实现这个效果。 
1、总体思路,为了简单不想监控很多手势问题,因此投机取巧的采用下面的方式来实现,

  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不想写太复杂(主要是没有人看,就自己看,稍稍写写)。
2、说了这么多,可能看的人的还是不怎么明白,下面就来看代码吧 
a. 首先是界面布局,保护两层,底层一个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>
登录后复制

b. 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>
登录后复制

c .公共部分布局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 style="@style/horizontal_gray_divider" />
 
  <View style="@style/horizontal_gray_divider" />
 
</LinearLayout>
登录后复制

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

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,并且能左右切换的效果。

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。

更多Android Listview上下拉动刷新tab滑动切换功能相关文章请关注PHP中文网!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1676
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
公司安全软件导致应用无法运行?如何排查和解决? 公司安全软件导致应用无法运行?如何排查和解决? Apr 19, 2025 pm 04:51 PM

公司安全软件导致部分应用无法正常运行的排查与解决方法许多公司为了保障内部网络安全,会部署安全软件。...

如何将姓名转换为数字以实现排序并保持群组中的一致性? 如何将姓名转换为数字以实现排序并保持群组中的一致性? Apr 19, 2025 pm 11:30 PM

将姓名转换为数字以实现排序的解决方案在许多应用场景中,用户可能需要在群组中进行排序,尤其是在一个用...

如何使用MapStruct简化系统对接中的字段映射问题? 如何使用MapStruct简化系统对接中的字段映射问题? Apr 19, 2025 pm 06:21 PM

系统对接中的字段映射处理在进行系统对接时,常常会遇到一个棘手的问题:如何将A系统的接口字段有效地映�...

如何优雅地获取实体类变量名构建数据库查询条件? 如何优雅地获取实体类变量名构建数据库查询条件? Apr 19, 2025 pm 11:42 PM

在使用MyBatis-Plus或其他ORM框架进行数据库操作时,经常需要根据实体类的属性名构造查询条件。如果每次都手动...

IntelliJ IDEA是如何在不输出日志的情况下识别Spring Boot项目的端口号的? IntelliJ IDEA是如何在不输出日志的情况下识别Spring Boot项目的端口号的? Apr 19, 2025 pm 11:45 PM

在使用IntelliJIDEAUltimate版本启动Spring...

Java对象如何安全地转换为数组? Java对象如何安全地转换为数组? Apr 19, 2025 pm 11:33 PM

Java对象与数组的转换:深入探讨强制类型转换的风险与正确方法很多Java初学者会遇到将一个对象转换成数组的�...

电商平台SKU和SPU数据库设计:如何兼顾用户自定义属性和无属性商品? 电商平台SKU和SPU数据库设计:如何兼顾用户自定义属性和无属性商品? Apr 19, 2025 pm 11:27 PM

电商平台SKU和SPU表设计详解本文将探讨电商平台中SKU和SPU的数据库设计问题,特别是如何处理用户自定义销售属...

如何利用Redis缓存方案高效实现产品排行榜列表的需求? 如何利用Redis缓存方案高效实现产品排行榜列表的需求? Apr 19, 2025 pm 11:36 PM

Redis缓存方案如何实现产品排行榜列表的需求?在开发过程中,我们常常需要处理排行榜的需求,例如展示一个�...

See all articles