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

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



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

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

一:滑动条的实现。

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

也先看看效果图:



在这里的滑动原理是:自定义一个控件(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):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <LinearLayout
        android:id="@+id/my_layout"
        android:layout_width="match_parent"
        android:layout_height="50dip"
        android:gravity="center"
        android:orientation="horizontal"
        />
    <com.ywl.slidetitle.TransLateView
        android:id="@+id/move"
        android:layout_width="match_parent"
        android:layout_height="3dip"
        android:layout_marginTop="50dip"
        android:background="#00ff00"/>
    <View
        android:id="@+id/lines"
        android:layout_width="match_parent"
        android:layout_height="1dip"
        android:layout_below="@id/move"
        android:background="#00ff00"/>
    
    <android.support.v4.view.ViewPager
        android:id="@+id/my_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/move"/>

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

然后是在MainActivity中引用:

<pre name="code" class="java">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<ImageView> 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<ImageView>();

		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)
	{

	}
}

 
这样就实现了滑动条的滑动效果。











  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ywl5320

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值