滑动逐渐隐藏导航栏的实现

在今天和明天之间,有一段很长的时间,趁你还有精神的时候,请尽快的完成重要事项。
下面这件事就很重要,也不知道什么时候有的想法,一直拖到今天才完成了。
………………………………………..以上是废话可以过滤………………………………………………

打开手机登录 QQ找到 好友动态进入,滑动页面看一下它的导航栏的变化。
今天的任务就是把这个功能用到项目中去。
仔细观察然后分析,得出的结果是看着简单做起来难(针对我这样的菜鸟)。
效果图:

分析一下:
a : 页面滑动的距离
b :图片的高度
c : 导航栏的高度
d : 开始设置导航栏背景透明度的高度

当 a < d 时设置导航栏背景为完全透明

当 a = b-2c = d 时开始设置导航栏背景透明度,在这期间随着手指滑动而改变背景透明度

当 a >= b 时 设置为不完全透明。

a< b-2c : 透明度设置为 0

a>=b    : 透明度设置为 255

怎么让它随着手指滑动而改变透明度呢。

这个问题还是留到代码里再说比较好。

Activity的布局文件:


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
<ScrollView
    android:id="@+id/id_scrollView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/photoWall"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@drawable/flower"
            android:scaleType="fitXY"/>

        <ListView
            android:id="@+id/id_listView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        ListView>

    LinearLayout>
ScrollView>
    <LinearLayout
        android:id="@+id/titleBar"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:gravity="center"
        android:background="@android:color/holo_blue_light">
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="55dp"
            android:gravity="center"
            android:textSize="22sp"
            android:text="好友动态"/>
    LinearLayout>

FrameLayout>

Activity:

package zyh.cn.com.demo_title;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * 滑动逐渐隐藏导航栏的实现
 */

public class SecondActivity extends AppCompatActivity implements View.OnTouchListener  {

    private ImageView mPhotoWall;
    private LinearLayout mTitleBar;
    private ScrollView mScrollView;
    private ListView mListView;
    private TextView mTitle;


    //图片的高度
    private float imageViewHeight;
    //titlebar的高度
    private float titleBarHeight;
    //滑动的距离
    private float scrollY;
    //开始设置透明度的高度
    private float startHeight;
    private ArrayList mArrayList;
    private ArrayAdapter mAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.qq_haoyoudongtai);
        initView();

    }

    private void initView() {
        mTitleBar = (LinearLayout) findViewById(R.id.titleBar);
        mTitle = (TextView) findViewById(R.id.title);
        mScrollView = (ScrollView) findViewById(R.id.id_scrollView);
        mScrollView.setOnTouchListener(this);
        mPhotoWall = (ImageView) findViewById(R.id.photoWall);
        mListView = (ListView) findViewById(R.id.id_listView);
        //让ListView失去焦点 
        mListView.setFocusable(false);
        mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, getDatas());
        mListView.setAdapter(mAdapter);
        setListViewHeight(mListView);

        mTitleBar.getBackground().setAlpha(0);

        imageViewHeight = getViewHeight(mPhotoWall);
        titleBarHeight = getViewHeight(mTitleBar);
        startHeight = imageViewHeight-2*titleBarHeight;

        Log.i("zyh ","imageViewHeight  :"+imageViewHeight );
        Log.i("zyh ","titleBarHeight  :"+titleBarHeight );
        Log.i("zyh ","startHeight  :"+startHeight );
        Log.i("zyh ","mTitle  :"+getViewHeight(mTitle) );
        Log.i("zyh ","Dp2Px  55dp to px  :"+Dp2Px(55) );

    }

    public int Dp2Px( float dp) {
        final float scale = this.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    /**
     * 测量控件的高度
     * @param view
     * @return
     */
    private float getViewHeight(View view) {
        int w = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        view.measure(w, h);
        Log.i("zyh","Height :  "+view.getMeasuredHeight());
        return  view.getMeasuredHeight();
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {

            case MotionEvent.ACTION_MOVE:
                scrollY= mScrollView.getScrollY();
                setUpTitleBarBackground(scrollY);
                break;
        }
        return false;
    }

   /**
     *  动态设置导航栏背景透明度
     * @param scrollY
     */
    private  void setUpTitleBarBackground(float scrollY){

        Log.i("Zyh--setUpTitleBarBackg","ScrollY  :"+scrollY);

        if (scrollY <=startHeight ){
            mTitleBar.getBackground().setAlpha(0);
        }else  if (scrollY> startHeight && scrollY <= imageViewHeight-titleBarHeight) {
            //注意这个值 它是关键  
            float realHeight = scrollY-startHeight;
            Log.i("Zyh--realHeight  :", "" + realHeight);
            //(有效的滑动距离 - 开始设置透明度的高度)/ 导航栏的高度 * 255就是我们要的透明度了 
            int alpha = (int)Math.floor((realHeight / titleBarHeight * 255));
            Log.i("Zyh--alpha", "alpha  :" + alpha);
            //将我们计算好的透明度 赋值给导航栏就可以了。
            mTitleBar.getBackground().setAlpha(alpha);
        }else if (scrollY >imageViewHeight ){
            mTitleBar.getBackground().setAlpha(255);
        }

    }

    /*
    假数据
     */
    private ArrayList getDatas() {
        mArrayList = new ArrayList();
        for (int i = 0; i < 30; i++) {
            mArrayList.add("重要的事情說   :" + i + "   遍");
        }
        return mArrayList;
    }

    /*
        ScrollView嵌套ListView 需要重新计算ListView的高度
     */

    public void setListViewHeight(ListView listView) {

        if (listView == null)
            return;

        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        /*Log.i("cbw", "======" + listAdapter.getCount());*/
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
            /*Log.i("cbw", "listview高度 ===== " + String.valueOf(i) + "======" + String.valueOf(totalHeight));*/
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1) );
        /*Log.i("cbw", "==总高度==" + String.valueOf(params.height));*/
        listView.setLayoutParams(params);
    }

}

说明:
这里只是为了实现 滑动逐渐隐藏导航栏功能,布局文件就简单多了,一个导航栏、一个照片墙、 一个ListView、外加一个ScrollView 。

1、获取导航栏高度的时候需要注意,刚开始我只设置了LinearLayout的Height为55dp 然后获取它的getMearsureHeight(); 感觉不太对,有点小。我猜想是不是获取的是它的子控件TextView的Height。为了验证我的猜想 就获取控件TextView的高度一对比 ,果然如此。 解决办法有多种 ,我为了省事儿,直接设置TextView的高度为55dp。
2、透明度是0~255之间 ,不是 0~100。
3、理解 动态设置透明度的那段代码

文章结束。

代码如有不规范,或者错误的地方还望大神们指出…. 如果有更好的方式实现 也请不要吝啬指教。
源码下载
源码说明:运行以后第一个也可以滑动看效果。主要是第二个Activity。

你可能感兴趣的:(android)