首页 > 代码库 > 透明度可变的标题栏效果实现

透明度可变的标题栏效果实现

我们在做类似于个人主页类应用的时候,可能会遇到这样的需求,效果如下



相信大家应该看明白是什么效果了,就是随着列表的滑动,上面的标题栏的透明度会随之变化。在IOS中,有很多的软件有这种效果,下面,我们看一下这种效果是如何实现的。

先看一下项目的目录


我们可以看到,目录结构很简单,因为我这个地方是使用的XListview代替的Listview,有很多文件都是XListview自带的,所以显得文件多一些,如果没使用过XListview,请先百度XListview看看。

这里面,我们需要重点关注的只有一个文件,就是MainActivity,我们的关键代码都在这里,下面,我们看一下代码实现

/**
 * 透明度可变的标题栏
 * 
 * @author Zhao KaiQiang
 * 
 * @Time 2014-6-20 上午11:46:42
 */
public class MainActivity extends Activity implements OnScrollListener {

	private XListView listView;
	// 标题栏的布局
	private RelativeLayout rl_title;
	// ListView的头布局
	private View headerView;
	// 头布局的高度
	private int headerHeight;
	private LayoutInflater inflater;
	private Handler handler = new Handler();

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

		rl_title = (RelativeLayout) findViewById(R.id.rl_title);
		listView = (XListView) findViewById(R.id.list);

		rl_title.getBackground().setAlpha(0);
		inflater = LayoutInflater.from(this);
		headerView = inflater.inflate(R.layout.header_listview, null);
		// 添加头布局
		listView.addHeaderView(headerView);
		listView.setAdapter(new MyAdapter());
		// 设置滚动监听
		listView.setOnScrollListener(this);
		// 设置可以刷新与加载更多
		listView.setPullLoadEnable(true);
		listView.setPullRefreshEnable(true);
		listView.setXListViewListener(new IXListViewListener() {

			@Override
			public void onRefresh() {
				// 单纯的模拟刷新过程
				handler.postDelayed(new Runnable() {

					@Override
					public void run() {
						listView.stopRefresh();
					}
				}, 500);
			}

			@Override
			public void onl oadMore() {
				// 单纯的模拟加载过程
				handler.postDelayed(new Runnable() {

					@Override
					public void run() {
						listView.stopLoadMore();
					}
				}, 500);
			}
		});

	}

	// 自定义适配器
	private class MyAdapter extends BaseAdapter {

		// 默认显示10个item
		@Override
		public int getCount() {
			return 10;
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = inflater.inflate(R.layout.item_list, null);
			}

			return convertView;
		}

	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {

	}

	// 最重要的方法,标题栏的透明度变化在这个方法实现
	@Override
	public void onScroll(AbsListView listView, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		// 判断当前最上面显示的是不是头布局,因为Xlistview有刷新控件,所以头布局的位置是1,即第二个
		if (firstVisibleItem == 1) {
			// 获取头布局
			View view = listView.getChildAt(0);
			if (view != null) {
				// 获取头布局现在的最上部的位置的相反数
				int top = -view.getTop();
				// 获取头布局的高度
				headerHeight = view.getHeight();
				// 满足这个条件的时候,是头布局在XListview的最上面第一个控件的时候,只有这个时候,我们才调整透明度
				if (top <= headerHeight && top >= 0) {
					// 获取当前位置占头布局高度的百分比
					float f = (float) top / (float) headerHeight;
					rl_title.getBackground().setAlpha((int) (f * 255));
					// 通知标题栏刷新显示
					rl_title.invalidate();
				}
			}
		} else if (firstVisibleItem > 1) {
			rl_title.getBackground().setAlpha(255);
		} else {
			rl_title.getBackground().setAlpha(0);
		}
	}

}

代码是不是不复杂?我们只需要实现onScroll方法就可以,在这里面,完成我们对HeaderView的位置的检测,然后通过HeaderView的高度和显示的高度来计算比例,设置到TitleBar的背景图片的透明度即可。