Android仿微信滑动导航栏的实现(上)

在微信5.3.1Android版本中,微信的导航栏切换的效果很不错,切换标题是,滑动条是滑动过去的,而不是直接跳过去的,给人一种很舒服的动画感觉。在这里,我就说说我对实现这种效果的理解,俗话说:眼见为实,先看看效果图吧:

Android仿微信滑动导航栏的实现(上)_第1张图片

Android仿微信滑动导航栏的实现(上)_第2张图片

怎样,效果是不是一样的,只是没有照搬微信里面的素材而已。

实现这个效果,我们先分步骤实现:

一:滑动条的实现。

首先,我是在上一次讲的 Android 启动引导页(动态生成底部导航圆点)的基础上添加的滑动功能(由于重建了项目文件,所以就把地图导航小圆点给去掉了,本来也不是本文的重点),没有看过的可以先看看,再看本文,效果才更好。

也先看看效果图:

Android仿微信滑动导航栏的实现(上)_第3张图片

Android仿微信滑动导航栏的实现(上)_第4张图片

在这里的滑动原理是:自定义一个控件(TransLateView继承自view),当此控件初始化时,获取控件的宽度,然后根据所要显示的节点(标题)数,计算出每个节点的宽度,然后在onDraw函数中,以某一点为起点(当然这是我们可以在程序中自己定义的,这是重点),绘制节点长度的一条直线,就实现了滑动条的绘制,然后动态的改变绘制的起点,就能实现滑动条的滑动条效果。

自定义控件(TransLateView)代码如下:

package com.ywl.slidetitle;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

public class TransLateView extends View {
	
	private float x = 0;// 滑动条的起始坐标
	private float initX = 0;// 每个节点的宽度(即:滑动条的宽度)
	Paint paint = new Paint();

	public TransLateView(Context context) {
		super(context);
	}
	
	public TransLateView(Context context, AttributeSet attribute)
	{
		super(context, attribute);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		paint.setColor(Color.BLUE);
		paint.setStrokeWidth(15);
		// 绘制滑动条,x为起始坐标,initX + x为终止坐标,就绘制了一条蓝色的线(滑动条)
		canvas.drawLine(0 + x, 0, initX + x, 0, paint);
	}

	/**
	 * 传入要实现滑动的节点数(即:标题数),再根据节点数计算出每一个节点所占的宽度,然后在onDraw函数中绘制。
	 * 
	 * @param count
	 */
	public void setInitX(final int count)
	{
		// 这是在加载控件时获取控件的总宽度(不一定是屏幕宽度,而是在布局文件中我们设置的:layout_width=“***”的宽度。
		// 然后除以节点数,得到的就是每个节点要显示的长度
		getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			@Override
			public void onGlobalLayout() {
				initX = (float)getWidth() / count;
				invalidate();
			}
		});
		
	}

	/**
	 * 得到此控件的宽
	 * 
	 * @return
	 */
	public float getW()
	{
		invalidate();
		return initX;
	}

	/**
	 * x:绘制滑动条的起始X坐标
	 * 
	 * @param x
	 */
	public void setXx(float x)
	{
		this.x = x;
		invalidate();
	}
}

原理我已经说了,代码里注释也比较详细,这里也就不再多说什么了,很简单的。

然后是在MainActivity中的使用:

先看看布局文件(activity_main.xml):



    
    
    
    
    


其中“com.ywl.slidetitle.TransLateView”控件就是我们自定义的控件,只需设置它的长度和宽度就行,为了美观,可以设置背景颜色等等其他的效果。

然后是在MainActivity中引用:

package com.ywl.slidetitle;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Toast;

public class MainActivity extends Activity implements OnPageChangeListener
{

	private ViewPager vPager;
	private VpAdapter vpAdapter;
	private TransLateView move;
	private static int[] imgs = { R.drawable.img1, R.drawable.img2,
			R.drawable.img3 };// 要显示的图片资源
	private ArrayList imageViews;// 用于包含引导页要显示的图片

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		vPager = (ViewPager) findViewById(R.id.my_viewpager);
		move = (TransLateView) findViewById(R.id.move);
		move.setInitX(3);// 设置节点数(标题数)
		initImages();

		vpAdapter = new VpAdapter(imageViews);
		vPager.setAdapter(vpAdapter);
		vPager.setOnPageChangeListener(this);
	}

	/**
	 * 把引导页要显示的图片添加到集合中,以传递给适配器,用来显示图片。
	 */

	private void initImages()
	{
		LayoutParams mParams = new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT);// 设置每一张图片都填充窗口
		imageViews = new ArrayList();

		for (int i = 0; i < imgs.length; i++)
		{
			ImageView iv = new ImageView(this);
			iv.setLayoutParams(mParams);// 设置布局
			iv.setImageResource(imgs[i]);// 为Imageview添加图片资源
			iv.setScaleType(ScaleType.FIT_XY);// 设置图片拉伸效果
			imageViews.add(iv);
			if (i == imgs.length - 1)// 为最后一张添加点击事件
			{
				iv.setOnClickListener(new OnClickListener()
				{

					@Override
					public void onClick(View v)
					{
						Toast.makeText(MainActivity.this, "跳转。。。",
								Toast.LENGTH_SHORT).show();
					}
				});
			}
		}
	}

	/**
	 * 根据引导页的数量,动态生成相应数量的导航小圆点,并添加到LinearLayout中显示。
	 */

	@Override
	public void onPageScrollStateChanged(int arg0)
	{

	}

	/**
	 * 动态绘制滑动条: arg0:表示实在第几个页面,也就是标题。arg0乘以滑动条的宽度,就是没有滑动时滑动条绘制的起始坐标。
	 * arg1:为页面偏移百分比,滑动时,偏移窗口左边的偏移量。偏移量乘以滑动条的宽度再加上,静止时的坐标,就是动态绘制时的起始坐标
	 * 起始坐标确定了,绘制滑动条就交给自定义控件里的onDraw绘制就可以了.
	 */
	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2)
	{
		move.setXx((float) arg0 * move.getW() + move.getW() * arg1);
	}

	/**
	 * arg0:当前滑动显示页面的索引值,可以根据这个值,来设置相应小圆点的状态。
	 */
	@Override
	public void onPageSelected(int arg0)
	{

	}
}

 
  
这样就实现了滑动条的滑动效果。
Android仿微信滑动导航栏的实现(上)_第5张图片

Android仿微信滑动导航栏的实现(上)_第6张图片

Android仿微信滑动导航栏的实现(上)_第7张图片









你可能感兴趣的:(实用功能)