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