android 自动隐藏控件,android自定义ListView实现底部View自动隐藏和消失的功能

有这样一个ListView,要求在屏幕底部有一个筛选排序的浮动框:

1、手指下拉隐藏,上滑显示 ;

2、如果没做任何操作,2S之后,要自动显示;

3、滑动到最底部,始终显示。

首先看其效果图:

250bf1aca49609a58445b61a216e9d2c.png

实现上述效果,其实现原理如下:

1、在屏幕顶部固定一个BottomView,XML布局最好使用RelativeLayout(底部的BottomView并不是 ListView的footView,这个是和footView独立的,想想为什么?)

2、然后自定义ListView控件,监听onTouchEvent事件,主要是监听手指下滑和上滑事件,同时实现onScrollListener,监听是否滑动到最底部和最顶部

3、 ListView监听事件中,控制bottomView的显示和隐藏,所以ListView提供一个接口,设置底部bootomView的内容,然后获之后,就可以对bottomView进行控制,同时加上动画效果。

接下来看是如何的具体实现这种效果:

1。底部BottomView的内容如下,这个XML文件的内容是自定义的,根据各项目的内容需求来定义的,我例子中bottom_view.xml:

android:id="@+id/button_layout"

android:layout_width="fill_parent"

android:layout_height="50dp"

android:background="#cbcbcb"

android:gravity="center_vertical"

android:orientation="horizontal" >

android:layout_width="wrap_content"

android:layout_weight="1"

android:text="价格" />

android:layout_width="wrap_content"

android:layout_weight="1"

android:text="好评" />

android:layout_width="wrap_content"

android:layout_weight="1"

android:text="筛选" />

2、main.xml如下

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:id="@+id/listView"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:fadingEdge="none"

/>

android:id="@+id/bottombar"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

layout="@layout/bottom_view"

>

3、自定义ListView控件BottomFloatListView

package com.example.BottomFloatListView;

import android.content.Context;

import android.os.Handler;

import android.util.AttributeSet;

import android.util.Log;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

import android.view.animation.Animation;

import android.view.animation.OvershootInterpolator;

import android.view.animation.TranslateAnimation;

import android.widget.*;

import android.widget.AbsListView.OnScrollListener;

/**

* 底部View自动隐藏和消失listview(其他ListView可以继承该类,如CtripBottomRefreshListView类等)

**/

public class BottomFloatListView extends ListView implements OnScrollListener {

public View mBottomBar;

private int mCurrentScrollState;

private boolean bIsMoved = false;

private boolean bIsDown = false;

private int mDeltaY;

private float mMotionY;

private int oldFirstVisibleItem = 0;

private Handler mHandler = new Handler();

private static final String TAG = "BottomFloatListView";

public BottomFloatListView(Context context) {

this(context, null);

super.setOnScrollListener(this);

}

public BottomFloatListView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

super.setOnScrollListener(this);

}

public BottomFloatListView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

super.setOnScrollListener(this);

}

@Override

public void setAdapter(ListAdapter adapter) {

super.setAdapter(adapter);

}

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

showBottomViewOnBottom(visibleItemCount, totalItemCount, firstVisibleItem);

}

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

hideBottomViewOnScrollStateChanged(view, scrollState);

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

float y = ev.getY();

float x = ev.getX();

Log.d("FloatListView", "onTouchEvent" + "" + x + "" + y);

int action = ev.getAction() & MotionEvent.ACTION_MASK;

switch (action) {

case MotionEvent.ACTION_DOWN:

action_down(y);

break;

case MotionEvent.ACTION_MOVE:

mDeltaY = (int) (y - mMotionY);

bIsMoved = true;

//移动的时候,要移除掉显示bottomView的消息

mHandler.removeCallbacks(showBottomBarRunnable);

//补齐action_down事件,因为有的时候,action_down 事件没有执行

action_down(y);

break;

case MotionEvent.ACTION_UP:

bIsMoved = false;

bIsDown = false;

if (!bIsMoved && !bIsDown) {

// 如果屏幕上什么没做,则过2s之后要显示bottomView

mHandler.postDelayed(showBottomBarRunnable, 2000);

}

if (mDeltaY < 0) { //下滑影藏

hideBottomBar();

} else { //上滑显示

showBottomBar();

}

bIsMoved = false;

break;

}

return super.onTouchEvent(ev);

}

private void action_down(float y){

mMotionY = y;

bIsDown = true;

Log.d(TAG, "action down execed");

mHandler.removeCallbacks(showBottomBarRunnable);

}

/**

* 滑动到顶部时,要隐藏bottomView

* @param view

* @param scrollState

*/

private void hideBottomViewOnScrollStateChanged(AbsListView view, int scrollState) {

mCurrentScrollState = scrollState;

if(view!=null){

if (view.getFirstVisiblePosition() == 0 && scrollState == SCROLL_STATE_IDLE) {

hideBottomBar();

Log.d(TAG, "hide bottom view");

}

}

}

/**

* 显示底部浮动栏

*/

public void showBottomBar() {

if (mBottomBar != null && mBottomBar.getVisibility() == View.GONE) {

mBottomBar.setVisibility(View.INVISIBLE);

Animation translateAnimation = new TranslateAnimation(mBottomBar.getLeft(), mBottomBar.getLeft(),30, 0);

translateAnimation.setDuration(300);

translateAnimation.setInterpolator(new OvershootInterpolator(0.6f));

mBottomBar.startAnimation(translateAnimation);

translateAnimation.setAnimationListener(new Animation.AnimationListener() {

@Override

public void onAnimationStart(Animation animation) {

}

@Override

public void onAnimationRepeat(Animation animation) {

}

@Override

public void onAnimationEnd(Animation animation) {

mBottomBar.setVisibility(View.VISIBLE);

}

});

}

}

/**

* 隐藏浮动底部栏

*/

private void hideBottomBar() {

if (mBottomBar != null && mBottomBar.getVisibility() == View.VISIBLE) {

Animation translateAnimation = new TranslateAnimation(mBottomBar.getLeft(), mBottomBar.getLeft(), 0, 30);

translateAnimation.setDuration(300);

translateAnimation.setInterpolator(new OvershootInterpolator(0.6f));

mBottomBar.startAnimation(translateAnimation);

translateAnimation.setAnimationListener(new Animation.AnimationListener() {

@Override

public void onAnimationStart(Animation animation) {

}

@Override

public void onAnimationRepeat(Animation animation) {

}

@Override

public void onAnimationEnd(Animation animation) {

mBottomBar.setVisibility(View.GONE);

}

});

}

}

/**

* 滑动到底部时直接显示bottomView

* @param visibleItemCount

* @param totalItemCount

* @param firstVisibleItem

*/

private void showBottomViewOnBottom(int visibleItemCount, int totalItemCount, int firstVisibleItem) {

Log.d(TAG, "visible bottem item count:" + "firstVisibleItem:" + firstVisibleItem + "oldFirstVisibleItem:" + oldFirstVisibleItem + mBottomBar);

if(getLastVisiblePosition() == totalItemCount -1 && mCurrentScrollState != SCROLL_STATE_IDLE){

showBottomBar();

}

}

private Runnable showBottomBarRunnable = new Runnable() {

@Override

public void run() {

showBottomBar();

}

};

/**

* 将需要隐藏显示的view传入

*

* @param bottomBar

*/

public void setBottomBar(ViewGroup bottomBar) {

this.mBottomBar = bottomBar;

}

}

4、主界面测试的Activity,MainActivity代码如下

public class MainActivity extends Activity {

private BottomFloatListView mBottomFloatListView;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mBottomFloatListView = (BottomFloatListView)findViewById(R.id.listView) ;

mBottomFloatListView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1,getData()));

ViewGroup bottomView = (ViewGroup)findViewById(R.id.bottombar) ;

mBottomFloatListView.setBottomBar(bottomView);

}

private List getData(){

List data = new ArrayList();

for(int i = 0; i <100; i++) {

data.add("测试数据" + i);

}

return data;

}

}

ViewGroup bottomView = (ViewGroup)findViewById(R.id.bottombar) ;

mBottomFloatListView.setBottomBar(bottomView);

将底部的bottomView传入到ListView中,就可以让ListView具有底部View自动隐藏和消失的功能。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现省份和城市的联动选择和显示,可以使用两个ListView控件,一个用于显示省份,另一个用于显示城市。当用户选择某个省份时,根据该省份所属的城市列表,更新城市ListView的数据源。 以下是一个简单的实现过程: 1. 在布局文件中添加两个ListView控件,分别用于显示省份和城市: ```xml <ListView android:id="@+id/province_list" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ListView android:id="@+id/city_list" android:layout_width="match_parent" android:layout_height="wrap_content" /> ``` 2. 在代码中获取两个ListView控件的引用,并设置适配器: ```java ListView provinceList = findViewById(R.id.province_list); ListView cityList = findViewById(R.id.city_list); // 设置省份ListView的适配器 ArrayAdapter<String> provinceAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, provinceListData); provinceList.setAdapter(provinceAdapter); // 设置城市ListView的适配器 ArrayAdapter<String> cityAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, cityListData); cityList.setAdapter(cityAdapter); ``` 其中,`provinceListData`和`cityListData`分别是省份和城市的数据源,可以从本地文件或网络获取。 3. 设置省份ListView的选择监听器,在选择某个省份时更新城市ListView的数据源: ```java provinceList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 获取选中的省份名称 String province = provinceListData.get(position); // 根据省份名称获取城市列表 List<String> cities = getCityListByProvince(province); // 更新城市ListView的数据源 cityListData.clear(); cityListData.addAll(cities); cityAdapter.notifyDataSetChanged(); } }); ``` 其中,`getCityListByProvince`是一个自定义方法,用于根据省份名称获取该省份所属的城市列表。 4. 完成以上步骤后,运行程序即可看到联动选择和显示效果。 以上是一个简单的实现过程,实际应用中可能需要更复杂的逻辑和界面设计。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值