Android 上滑显示底部导航,下滑显示标题bar

 本文简单介绍使用属性动画来实现上滑显示底部导航,下滑显示标题bar。先上图看效果,再分析:


可以看出这是个listview有标题和底部,有点像下拉刷新和上拉加载更多。只不过下拉或上拉一定时位置固定拉不动,且只在list的第一个item出现显示时,才平滑动画的让标题或底部显示或隐藏。

实现思路:

    1、整个布局有三个部分构成,上部由一个RelativeLayout放ImageView或TextView.中间部分是个listView,下部是一个TextView.

    2、采用LinearLayout摆放中下部分,让屏幕初始时把上部分移出屏幕外面。中间listview与底部往上移。

    3、采用平移动画,移动动画有两种一种tween动画一种属性动画。而tween动画是假移事件焦点还在原来地方,而属性动画则是3.0支持的为了兼容3.0以下的这里采用nineoldandroids。

    4、通过给listview设置touch listener,监听手掼是向下滑动的(Y比X移动距离大)且滑动距离足够大时,判断是向下反之亦然是向上。event move过程会有多次回调,为了保证在一次dowm 向下滑动时,需要在down 时设置标志,来保证一次down 向下滑动时只调用动画一次 做显示标题动作。

上代码:

  布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/id_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
     >
    <!-- 上部分 -->
    <RelativeLayout 
        android:id="@+id/rl_title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#A8A8A8"
        >
        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="20dp"
            android:layout_centerVertical="true"
            android:src="@drawable/icon_back"
            />
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="标题111"
            android:layout_centerInParent="true"
            android:textColor="#000000"
            />
         <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="20dp"
            android:layout_centerVertical="true"
            android:src="@drawable/icon_search"
            />
    </RelativeLayout>
    
    <ListView
        android:id="@+id/lv_data"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:listSelector="@null"
        android:dividerHeight="1dp"
        android:divider="#a5a5a5"
         />
        
     <!-- 下部分 -->
    <TextView 
        android:id="@+id/tv_bottom"
         android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="我是底部的栏目"
        android:textSize="18sp"
        android:textColor="#ffffff"
        android:background="#a3a3a3"
        android:gravity="center"
        />
    

</LinearLayout>

package com.test.projecta;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.nineoldandroids.animation.ObjectAnimator;

public class HideShowTitleActivity extends Activity {

	private RelativeLayout rl_title;
	private ListView lv_data;
	
	private List<String> mListDatas;
	private boolean mIsShowTitle = false;
	private float mTranslateY;
	private boolean mIsfirstVisible = true;
	private TextView tv_bottom;
	private float mBottomHeight;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_newhideshowtitlelist_back);
		
		findView();
		setListener();
		doLogic();
	}
	
	private void findView() {
		rl_title = (RelativeLayout) findViewById(R.id.rl_title);
		lv_data = (ListView) findViewById(R.id.lv_data);
		tv_bottom = (TextView) findViewById(R.id.tv_bottom);
	}
	
	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		if(hasFocus){
			//获取listview的高度   那么bottom开始的位置是mTranslateY+height值 
			int height = lv_data.getHeight();
			mBottomHeight = mTranslateY + height;
			showHideTitle(false,0);
		}
	}

	private void setListener() {
		lv_data.setOnScrollListener(new OnScrollListener() {
			
			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				
			}
			
			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				//判断当前是否在显示list的第一项数据
				mIsfirstVisible = firstVisibleItem==0;
				//手掼滑动太快时非显示第一项还显示标题时,隐藏掉标题
				if(mIsShowTitle && !mIsfirstVisible){
					showHideTitle(false,500);
				}
			}
		});
		lv_data.setOnTouchListener(new OnTouchListener() {
			private float lastX;
			private float lastY;
			boolean isChange = false;
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					lastX = event.getX();
					lastY = event.getY();
					isChange = false;
					return false;
				case MotionEvent.ACTION_MOVE:
					float x = event.getX();
					float y = event.getY();
					float xGapDistance = Math.abs(x-lastX);
					float yGapDistance = Math.abs(y-lastY);
					boolean isDown = y-lastY>5;
					//没有显示标题时,且是向下的,就显示
					boolean isShow = yGapDistance > 8 && xGapDistance<8 && !mIsShowTitle  && isDown;
					boolean isHide = yGapDistance > 8 && xGapDistance<8 && mIsShowTitle  && !isDown;
					lastX = x;
					lastY = y;
					//一次down,只变化一次,防止一次滑动时抖动下,造成某一个的向下时,y比lastY小
					if(!isChange&&mIsfirstVisible&&isShow){
						// 显示此标题
						showHideTitle(true,500);
						isChange = true;
					}//显示标题时,且是向上的,就隐蔽
					 else if(!isChange&&mIsfirstVisible&&isHide){
						// 隐蔽标题
						 showHideTitle(false,500);
						 isChange = true;
					}
					break;

				default:
					break;
				}
				return false;
			}
			
		});
	}

	private void showHideTitle(boolean isShow,int duration) {
		if(isShow){
			ObjectAnimator.ofFloat(lv_data, "y",0,mTranslateY).setDuration(duration).start();
			ObjectAnimator.ofFloat(rl_title, "y", -mTranslateY,0).setDuration(duration).start();
			ObjectAnimator.ofFloat(tv_bottom, "y", mBottomHeight-mTranslateY,mBottomHeight).setDuration(duration).start();
			
		}else{//隐藏时,把标题隐藏了,底部出来了
			ObjectAnimator.ofFloat(lv_data, "y", mTranslateY,0).setDuration(duration).start();
			ObjectAnimator.ofFloat(rl_title, "y", 0f,-mTranslateY).setDuration(duration).start();
			ObjectAnimator.ofFloat(tv_bottom, "y", mBottomHeight,mBottomHeight-mTranslateY).setDuration(duration).start();
		}
		mIsShowTitle = isShow;
	}
	
	private void doLogic() {
		mListDatas = new ArrayList<String>();
		for(int i=0;i<50;i++){
			mListDatas.add("数据"+i);
		}
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mListDatas);
		lv_data.setAdapter(adapter);
		//将标题栏高度50dp转成显示的高度
		mTranslateY = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
	}
	
}

转自:http://blog.csdn.net/chenshufei2/article/details/47317491


扩展:

android ListView向上滑动隐藏标题,下拉显示标题栏,完美解决滑动出现的空白问题。


http://download.csdn.net/detail/tuibiansoar/8153269

### 回答1: 在 Android 系统中,配置导航栏显示需要对系统 UI 进行相应的设置和操作。一般来说,这个过程需要遵循以下几个步骤: 1. 打开 Android 系统设置,并找到“系统 UI tuner”选项。 2. 进入“System UI Tuner”页面,选择“Navigation bar”选项。 3. 在“Navigation bar”页面,勾选“Swipe up on home button”选项。 4. 接下来,用户可以根据自己的需要选择相应的设置项。比如,可以选择当用户在主屏幕动或者点击主屏幕按钮时,导航栏是否应该显示。还可以设置是否需要快速启动 Google 助手或其他应用。另外,还可以设置不同手势触发不同导航栏功能或者更改导航栏的界面样式等。 5. 最后,如果您想要禁用这个特性,只需要在“Navigation bar”页面取消勾选“Swipe up on home button”选项即可。 需要注意的是,以上步骤仅适用于当前运行的 Android 版本中存在“System UI Tuner”选项的设备。此外,一些 Android 设备可能会拥有各自不同的配置选项和界面,所以在实际操作时,最好先了解自己的设备型号和 Android 版本,并参考相应的用户手册或者官方文档。 ### 回答2: Android系统UI配置导航栏显示,主要是通过系统的设置菜单来实现。在大多数的Android设备中,该功能都是默认开启的,但是在某些旧型号的设备上,可能需要手动开启才能使用。 为了开始配置导航栏显示,首先需要进入系统的设置菜单。具体进入方式可能会因设备型号而异,但通常可以通过从主屏幕或应用程序菜单中选择“设置”来进入。 打开设置菜单后,需要找到“显示”或“屏幕”选项。然后,可以在下拉菜单中找到“导航栏”选项,点击进入。 在导航栏设置中,可以看到“导航栏显示”选项。默认情况下,该选项应该是开启状态,但如果不是,可以通过开关按钮来手动开启。 在开启导航栏显示功能后,可以测试它是否正常工作。要测试它,只需要在应用程序或主屏幕中向上动,应该会出现导航栏。如果导航栏出现,可能需要重新启动设备或检查是否有其他应用程序干扰导航栏显示。 需要注意的是,导航栏显示功能在Android系统中的不同版本中可能有所不同。在一些最新的系统版本中,导航栏显示可能已被替换为新的手势导航功能。因此,在进行上述设置时,需要查看设备所运行的Android系统版本,并根据版本进行相应的设置。 ### 回答3: Android 系统 UI 配置导航栏显示是指在 Android 手机或平板设备中,将导航栏的隐藏与显示控制与手势上事件进行了关联,使得用户在上操作时能够显示或者隐藏底部导航栏。 在 Android 操作系统中,导航栏通常位于设备底部,用于进行返回、主屏幕、多任务查看等基本操作。原本,导航栏不会自动隐藏,只有在使用全屏模式时才会自动隐藏,但是在 Android 操作系统 4.4(KitKat)版本中,Google 引入了一项新特性,允许用户启用手势上操作,使得导航栏能够随着手势上自动隐藏,并在需要时进行显示。 要在 Android 设备上启用这个选项,可以通过以下步骤进行配置: 1. 首先,确保您的 Android 设备运行的是 4.4 版本及以上的系统版本。 2. 进入系统设置界面,找到“显示”选项。 3. 在显示选项中,找到“导航栏”选项,点击进入该设置页面。 4. 在导航栏设置页面中,找到“全屏手势”选项,并将其打开。 5. 启用全屏手势之后,您就可以进行手势上显示或隐藏底部导航栏了。 需要注意的是,启用全屏手势选项后,手势上操作就会与设备的“向上动以解锁”功能进行了关联,因此您需要在动操作后进行解锁才能进入系统界面。 总的来说,Android 系统 UI 配置导航栏显示是一项非常实用的功能,可以提高用户的操作体验、提高屏幕使用率,并适用于绝大多数的 Android 手机和平板设备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值