仿微信6.0底部菜单选择和滑动效果

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">第一次写博客。。作为一个新手来说通过写博客来记录自己的学习历程和问题总结是一件非常有意义的事情。。</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">多的不说先看效果</span>

为了方便。。我是随便找了几张图片。。并没有对微信进行反编译获取其中的图片,各位将就这看看吧。多的不说先看代码


首先布局分析:

滑动切换fragment显而易见使用的是ViewPager..至于下面的菜单栏我并没有使用传统的TabHost而是自定义控件。。。大家可以看出下面

滑动过程中颜色是渐变的。。

自定义控件代码:

public class MyTabExchangeView extends View{

	private int iconColor=0xff45c01a;
	private int textColor=0xff45c01a;
	private float textSize=14f;
	private String textString="首页";
	private Bitmap mBitmap;
	private Paint mPaint;
	private int rectWidth;
	private int rectHeight;
	private int iconWidth;
	private Rect iconRect;
	private Paint mTextPaint;
	private Rect mTextRect=new Rect();
	private float mAlpha=0f;
	private Bitmap iconBitmap;
	public MyTabExchangeView(Context context, AttributeSet attrs) {
		super(context, attrs);
		TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.MyTabExchangeView);
		for (int i = 0; i < array.getIndexCount(); i++) {
			int type=array.getIndex(i);
			switch (type) {
			case R.styleable.MyTabExchangeView_iconColor:
				iconColor=array.getColor(type, 0xff45c01a);
				break;
			case R.styleable.MyTabExchangeView_iconDrawable:
				Drawable iconBitmapDrawable = array.getDrawable(type);
				iconBitmap=((BitmapDrawable)iconBitmapDrawable).getBitmap();
				break;
			case R.styleable.MyTabExchangeView_textColor:
				textColor=array.getColor(type, 0xff45c01a);
				break;
			case R.styleable.MyTabExchangeView_textSize:
				textSize=array.getDimension(type, 10);
				break;
			case R.styleable.MyTabExchangeView_textString:
				textString =array.getString(type);
				break;
			default:
				break;
			}
		}
		array.recycle();
		int textLength=textString.length();
		mTextPaint=new Paint();
		mTextPaint.setColor(textColor);
		mTextPaint.setTextSize(textSize);
		mTextPaint.getTextBounds(textString, 0, textLength, mTextRect);
		
	}
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//清空画板
		canvas.drawBitmap(iconBitmap, null, iconRect, null);
		int alpha=(int) Math.ceil(mAlpha*255);
		onDrawMyCanvas(alpha);
		drawSrcText(canvas,alpha);
		drawDstText(canvas,alpha);
		canvas.drawBitmap(mBitmap, 0, 0, null);
	}
	private void drawDstText(Canvas canvas, int alpha) {
		mTextPaint.setColor(textColor);
		mTextPaint.setAlpha(alpha);
		mTextPaint.setTextSize(textSize);
		canvas.drawText(textString,
				iconRect.left+iconRect.width()/2-mTextRect.width()/2,
				iconRect.bottom+mTextRect.height(), mTextPaint);
	}
	private void drawSrcText(Canvas canvas, int alpha) {
		mTextPaint.setColor(Color.BLACK);
		mTextPaint.setAlpha(255-alpha);
		mTextPaint.setTextSize(textSize);
		canvas.drawText(textString,
				iconRect.left+iconRect.width()/2-mTextRect.width()/2,
				iconRect.bottom+mTextRect.height(), mTextPaint);
	}
	private void onDrawMyCanvas(int alpha) {
		mBitmap=Bitmap.createBitmap(rectWidth, rectHeight, Config.ARGB_8888);
		Canvas mCanvas=new Canvas(mBitmap);
		mPaint=new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		mPaint.setColor(iconColor);
		mPaint.setAlpha(alpha);
		mCanvas.drawRect(iconRect, mPaint);
		mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
		mCanvas.drawBitmap(iconBitmap, null, iconRect, mPaint);
		
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		rectWidth=getMeasuredWidth();
		rectHeight=getMeasuredHeight();
		iconWidth=Math.min(rectWidth-getPaddingLeft()-getPaddingRight(),
				rectHeight-getPaddingTop()-getPaddingBottom()-mTextRect.height());
		int left=(rectWidth-iconWidth)/2;
		int top=(rectHeight-mTextRect.height()-iconWidth)/2;
		iconRect=new Rect(left, top, left+iconWidth, top+iconWidth);
	}
	public void setAlpha(float alpha){
		this.mAlpha=alpha;
		if (Looper.getMainLooper()!=Looper.myLooper()) {
			postInvalidate();
		}else {
			invalidate();
		}
	}
}
布局xml使用:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:ww="http://schemas.android.com/apk/res/com.ww.mybottomtitle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >

    <android.support.v4.view.ViewPager
        android:id="@+id/fragment_pager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@+id/bottom_title"
    />
    <LinearLayout
        android:id="@+id/bottom_title" 
        android:layout_width="fill_parent"
        android:layout_height="48dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:background="#F0F0F0"
        >
        <com.ww.mybottomtitle.MyTabExchangeView
            android:id="@+id/index"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            ww:textString="首页"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            ww:iconDrawable="@drawable/icon_home"
            ww:textSize="10sp"
            />
        <com.ww.mybottomtitle.MyTabExchangeView
            android:id="@+id/news"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            ww:textString="咨询"
            ww:iconDrawable="@drawable/icon_dingyue"
            ww:textSize="10sp"
            />
        <com.ww.mybottomtitle.MyTabExchangeView
            android:id="@+id/happy"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            ww:textString="娱乐"
            ww:iconDrawable="@drawable/icon_list"
            ww:textSize="10sp"
            />
        <com.ww.mybottomtitle.MyTabExchangeView
            android:id="@+id/myself"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            ww:textString="我"
            ww:iconDrawable="@drawable/icon_health_data"
            ww:textSize="10sp"
            />
            
    </LinearLayout>
</RelativeLayout><strong>
</strong>

主界面逻辑控制代码:

public class MainActivity extends FragmentActivity implements OnPageChangeListener{

	private ViewPager viewPager;
	private String[] menu_text={"首页","咨询","娱乐","个人"};
	private ArrayList<MyTabExchangeView> list=new ArrayList<MyTabExchangeView>();
	private MyViewPagerAdapter adapter;
	private MyTabExchangeView index,news,happy,myself;
	private boolean onClick=false;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
	}
	private void initView(){
		index=(MyTabExchangeView) findViewById(R.id.index);
		news=(MyTabExchangeView) findViewById(R.id.news);
		happy=(MyTabExchangeView) findViewById(R.id.happy);
		myself=(MyTabExchangeView) findViewById(R.id.myself);
		list.add(index);
		list.add(news);
		list.add(happy);
		list.add(myself);
		index.setOnClickListener(new onTitleButtonClickListener(0));
		news.setOnClickListener(new onTitleButtonClickListener(1));
		happy.setOnClickListener(new onTitleButtonClickListener(2));
		myself.setOnClickListener(new onTitleButtonClickListener(3));
		viewPager=(ViewPager) findViewById(R.id.fragment_pager);
		adapter=new MyViewPagerAdapter(getSupportFragmentManager(),menu_text);
		viewPager.setAdapter(adapter);
		viewPager.setOnPageChangeListener(this);
		viewPager.setOffscreenPageLimit(3);
		viewPager.setCurrentItem(0);
		index.setAlpha(1);
	}
	class onTitleButtonClickListener implements OnClickListener{
		private int position;
		public onTitleButtonClickListener(int position) {
			this.position=position;
		}
		@Override
		public void onClick(View v) {
			onClick=true;
			list.get(viewPager.getCurrentItem()).setAlpha(0);
			viewPager.setCurrentItem(position);
			list.get(viewPager.getCurrentItem()).setAlpha(1);
		}
		
	}
	@Override
	public void onPageScrollStateChanged(int arg0) {
		// TODO Auto-generated method stub
	}
	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		if (arg1>0&&!onClick) {
			MyTabExchangeView left = list.get(arg0);
			MyTabExchangeView right = list.get(arg0+1);
			left.setAlpha(1-arg1);
			right.setAlpha(arg1);
		}else {
			onClick=false;
		}
	}
	@Override
	public void onPageSelected(int arg0) {
		// TODO Auto-generated method stub
		
	}
	
}
至此代码差不多就到此结束了。。代码注释有些少。。以后再度添加。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Android中实现仿微信朋友圈底部的拍照和拍摄功能,可以通过使用系统自带的相机应用或者自定义相机来进行实现。 首先,可以使用系统自带的相机应用来实现拍照和拍摄的功能。可以通过调用Intent,使用ACTION_IMAGE_CAPTURE和ACTION_VIDEO_CAPTURE来启动相机应用,并通过设置Uri来指定图片或视频的保存路径。在拍摄完成后,可以在onActivityResult()方法中获取拍摄结果进行处理,比如保存图片或视频的Uri,显示预览等。 其次,也可以自定义相机来实现拍照和拍摄的功能。可以通过使用Camera和Camera2 API来实现相机的预览和拍摄功能。首先,需要使用Camera或Camera2 API来启动相机预览,并通过设置SurfaceHolder或SurfaceTexture来显示预览画面。同时,可以监听相机的拍照或拍摄按钮点击事件,在点击时进行拍照或拍摄操作,并通过设置相机的PictureCallback或CaptureCallback来处理拍摄结果。 无论是使用系统相机应用还是自定义相机,还可以添加一些额外的功能来实现更好的用户体验。比如,可以添加美颜滤镜、闪光灯控制、切换前后摄像头等功能。 总而言之,在Android中实现仿微信朋友圈底部的拍照和拍摄功能可以通过使用系统自带相机应用或自定义相机来实现,为用户提供类似微信朋友圈的相机功能,并可以根据需求添加额外的功能来增强用户体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值