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

在上一节 Android仿微信滑动导航栏的实现(上)中我们已经实现了导航条的滑动条效果,只是还没有添加标题栏,现在我们就把标题栏给加上:

效果图和源码在本文末尾处。

在这里增加了一个显示标题栏的自定义控件:TitleLayout,继承于LinearLayout,其原理是:根据传递的标题栏的标题(其中隐藏着标题的数量),动态生成对应标题内容的TextView来显示标题,并控制其在控件中居中显示,还提供了一个方法,用于返回生成的标题控件,为了在调用activity中为每个标题添加不同的相应,其代码如下:

package com.ywl.slidetitle;

import android.content.Context;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TitleLayout extends LinearLayout {

	public TextView[] textViews;// 标题栏数组,用于存储要显示的标题

	/**
	 * titles:即要显示的标题栏的数组
	 * 
	 * @param context
	 * @param titles
	 */
	public TitleLayout(Context context, String[] titles)
	{
		super(context);
		// 控件中的子空间整体横向排列,控件本身填充父控件
		this.setOrientation(HORIZONTAL);
		LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
		this.setLayoutParams(layoutParams);
		// 初始化,标题栏
		this.textViews = new TextView[titles.length];
		// 循环,根据标题栏动态生成TextView来显示标题,每个标题栏的宽度比例为1:1,其中的内容居中。
		for(int i = 0; i < titles.length; i++)
		{
			TextView textView = new TextView(context);
			textView.setText(titles[i]);
			textView.setGravity(Gravity.CENTER);
			textViews[i] = textView; 
			LayoutParams params = new LayoutParams(0,LayoutParams.WRAP_CONTENT);
			params.weight = 1;
			params.gravity = Gravity.CENTER;
			addView(textView, params);
		}
		
	}

	/**
	 * 获取标题栏的标题TextView控件,为了在MainActi中添加对标题栏点击事件的相应和切换。
	 * 
	 * @return
	 */
	public TextView[] getTextViews()
	{
		return textViews;
	}
}


布局文件activity_main没变:

<pre name="code" class="html"><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>

 id为my_layout的LinearLayout就是用来放置标题控件的。 

在MainActivity对标题控件的使用如下:

package com.ywl.slidetitle;

import java.util.ArrayList;

import android.app.Activity;
import android.graphics.Color;
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;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnPageChangeListener
{

	private ViewPager vPager;
	private VpAdapter vpAdapter;
	private TransLateView move;// 滑动条控件
	private TitleLayout myLayout;// 标题栏控件
	private LinearLayout titleLayout;// 用于包含标题栏控件

	private static int[] imgs = { R.drawable.img1, R.drawable.img2,
			R.drawable.img3 };// 要显示的图片资源
	private ArrayList<ImageView> imageViews;// 用于包含引导页要显示的图片

	private TextView[] textViews;// 存储标题栏返回的标题TextView控件
	private String[] titles = { "标题一", "标题二", "标题三" };// 要显示的标题

	@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);// 设置节点数(标题数)
		titleLayout = (LinearLayout) findViewById(R.id.my_layout);
		myLayout = new TitleLayout(this, titles);
		textViews = myLayout.getTextViews();
		for (int i = 0; i < textViews.length; i++)
		{
			if (i == 0)
			{
				textViews[i].setTextColor(Color.RED);
				;
			}
			final int id = i;
			textViews[i].setOnClickListener(new OnClickListener()
			{

				@Override
				public void onClick(View v)
				{
					// TODO Auto-generated method stub
					vPager.setCurrentItem(id);
				}
			});
		}
		titleLayout.addView(myLayout);
		move.setInitX(titles.length);
		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)
	{
		for (int n = 0; n < textViews.length; n++)
		{
			if (arg0 == n)
			{
				textViews[n].setTextColor(Color.RED);
			}
			else
			{
				textViews[n].setTextColor(Color.BLACK);
			}
		}
	}
}
 在activity中,主要是对TitleLayout控件的初始化,并添加到my_layout容器中,代码里注释也很详细,这里也不再啰嗦了。 

最终效果如下:

好了 ,全部搞定,哈哈哈

  源码免费下载















  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现Android仿微信语音手势滑动的功能,您可以使用GestureDetector类和MediaRecorder类。GestureDetector类可以帮助您检测滑动手势,MediaRecorder类可以帮助您录制音频文件。 以下是实现Android仿微信语音手势滑动的一些步骤: 1. 创建一个GestureDetector实例并将其附加到您的视图上。 2. 实现GestureDetector.OnGestureListener接口,以便您可以处理检测到的手势。您可以在onScroll回调方法中检测滑动手势,并根据手势方向执行相应的操作。 3. 在启动录音操作时,创建一个MediaRecorder实例,并配置它以录制音频文件。 4. 在停止录音操作时,停止MediaRecorder并保存录制的音频文件。 以下是一个简单的示例代码,演示如何使用GestureDetector和MediaRecorder实现Android仿微信语音手势滑动: ``` public class MyView extends View implements GestureDetector.OnGestureListener { private GestureDetector gestureDetector; private MediaRecorder mediaRecorder; private String audioFilePath; public MyView(Context context) { super(context); gestureDetector = new GestureDetector(context, this); audioFilePath = getExternalCacheDir().getAbsolutePath() + "/audio.3gp"; } @Override public boolean onTouchEvent(MotionEvent event) { return gestureDetector.onTouchEvent(event); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (distanceX > distanceY) { // 手势向右滑动,启动录音操作 startRecording(); } else { // 手势向左滑动,停止录音操作 stopRecording(); } return true; } private void startRecording() { mediaRecorder = new MediaRecorder(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setOutputFile(audioFilePath); try { mediaRecorder.prepare(); } catch (IOException e) { e.printStackTrace(); } mediaRecorder.start(); } private void stopRecording() { mediaRecorder.stop(); mediaRecorder.release(); mediaRecorder = null; // 在这里可以将录制的音频文件发送到服务器或保存到本地 } // 实现其他GestureDetector.OnGestureListener接口方法 // ... } ``` 希望这可以帮助您实现所需的功能。如果您有任何其他问题,请随时问我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ywl5320

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

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

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

打赏作者

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

抵扣说明:

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

余额充值