码迷,mamicode.com
首页 > 其他好文 > 详细

一个带动画的页面底部的TabBar的实现

时间:2016-01-09 20:09:26      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

有时有这样一个需求,页面底部有几个图标能够点击,假设一个screenWidth显示不下这些图标,则这一列图标最后一个是more,点击more,能够通过动画展示两列图标

这样来增加layout中:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FFFFFF" >

        <include
            android:id="@+id/title"
            layout="@layout/title_list" />

        <View
            android:id="@+id/line"
            android:layout_width="fill_parent"
            android:layout_height="2dip"
            android:layout_below="@id/title"
            android:background="@drawable/rc_list_divider" />

        <ListView
            android:id="@+id/mylist"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/title"
            android:background="@null"
            android:cacheColorHint="@color/bgColorMain"
            android:divider="@null"
            android:dividerHeight="0dp"
            android:fadeScrollbars="false"
            android:visibility="gone" >
        </ListView>

        <LinearLayout
            android:id="@+id/loading_layout"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_below="@id/line"
            android:background="@color/white"
            android:gravity="center" >

            <ProgressBar
                style="?android:attr/progressBarStyleLarge"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom" >

       <strong> <com.example.view.ExpandableView
            android:id="@+id/launcher_expand_view"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" /></strong>
    </RelativeLayout>

</FrameLayout>

代码里这样来写:

private void prepareLauncherView() {
		
		mRootView = LayoutInflater.from(this).inflate(R.layout.activity_main, null);
		setContentView(mRootView);
		
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		int screenWidth = dm.widthPixels;
		int height = dm.heightPixels;
		//取出底部几个Button的图标资源
		mLauncherDrawables = getResources().obtainTypedArray(R.array.launcher_item_drawables);
		
		mExpandableView = (ExpandableView) findViewById(R.id.launcher_expand_view);
		mItemViews = new ArrayList<View>();
		for (int i = 0; i < mLauncherDrawables.length(); i++) {
			addLauncherItem(i);
		}
		//点击more的时候响应(运行TransLate动画)
		mExpandableView.setOnExpandItemClickListener(this);
		
		int contentHeight = height - getStatusBarHeight();
		mExpandableView.setScreenSize(contentHeight, screenWidth);
		mExpandableView.addListView(mItemViews);
		
	}	
	
	@Override
	protected void onStart() {
		super.onStart();
		mExpandableView.setRestart(true);
	}

	private int getStatusBarHeight() {  <strong>//这个是取statusbar高度的做法</strong>

		Class<?

> c = null; Object obj = null; Field field = null; int x = 0, sbar = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field.get(obj).toString()); sbar = getResources().getDimensionPixelSize(x); } catch (Exception e1) { e1.printStackTrace(); } return sbar; } private void addLauncherItem(int i) { View view = LayoutInflater.from(this).inflate(R.layout.launch_bar_item, null).findViewById(R.id.launcher_content); view.setBackgroundDrawable(mLauncherDrawables.getDrawable(i)); mItemViews.add(view); } @Override public void onExpandItemClick(View parentView, View view, int position, int maxNum, int line) { if (!mExpandableView.isInAnimation()) { if (position != maxNum) { mExpandableView.excuteAnimation(false); } else { mExpandableView.excuteAnimation(true); } } }


关于ExpandableView这个类:

package com.example.view;

import java.util.List;

import com.example.shoplistdownload.R;

import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

public class ExpandableView extends LinearLayout {

	private int mScreenWidth;
	private int mScreenHeight;
	private int mButtonWidth;
	private int mButtonHeight;
	private LinearLayout mLayoutShow;
	private LinearLayout mLayoutHide;
	private ExpandItemClickListener onExpandItemClickListener;
	private int mMaxNum;
	private boolean mIsInAnimation = false;
	private boolean mCanMoveToBottom = false;
	private View mMoreView;
	private int mOldBottom;
	private Context mContext;
	private int mHeaderHeight;
	private double mAverageSize;
	private boolean mIsFirstLayout= true;
	private LinearLayout.LayoutParams mParams;
	private boolean mRestart = false;
	private LayoutInflater mInflater;
	public static final int LAUNCHER_BAR_LINE_ONE = 0;
	public static final int LAUNCHER_BAR_LINE_TWO = 1;
	
	private static final boolean LAUNCHER_HIDE_LAYOUT_TAG = true;

	
	public ExpandableView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		mInflater = LayoutInflater.from(mContext);
	}

	public void setScreenSize(int height, int width) {
		mScreenHeight = height;
		mScreenWidth = width;
		initParameter();
		initSubView();
	}
	
	private void initParameter(){
		mButtonWidth = mContext.getResources().getDimensionPixelSize(R.dimen.expand_item_minwidth);
		mButtonHeight = mContext.getResources().getDimensionPixelSize(R.dimen.expand_item_minheight);
		mHeaderHeight = mContext.getResources().getDimensionPixelSize(R.dimen.header_bar_height);
		mMaxNum = mScreenWidth / mButtonWidth;
		mAverageSize = ((double) mScreenWidth) / mMaxNum;
		this.setOrientation(LinearLayout.VERTICAL);
	}

	public void addListView(List<View> views) {
		setPortraitView(views);
		//mLayoutShow为第一列
		addView(mLayoutShow);
		//mLayoutHide为第二列,第一次展示时会隐藏
		addView(mLayoutHide);

	}
	
	private void initSubView() {
		mMoreView = mInflater.inflate(R.layout.launch_bar_item, null).findViewById(R.id.launcher_content);
		mMoreView.setBackgroundResource(R.drawable.btn_launcher_more);
		mMoreView.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				mRestart = false;
				onExpandItemClickListener.onExpandItemClick(mLayoutShow, v, mMaxNum, mMaxNum, LAUNCHER_BAR_LINE_ONE);
			}
		});
		
		mLayoutShow = new LinearLayout(mContext);
		mLayoutHide = new LinearLayout(mContext);
		mLayoutHide.setTag(LAUNCHER_HIDE_LAYOUT_TAG);
		mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, mButtonHeight);
		mLayoutShow.setOrientation(LinearLayout.HORIZONTAL);
		mLayoutHide.setOrientation(LinearLayout.HORIZONTAL);
		mLayoutShow.setBackgroundResource(R.drawable.bg_launcher_port_nor);
		mLayoutHide.setBackgroundResource(R.drawable.bg_launcher_port_nor);
		mLayoutShow.setLayoutParams(mParams);
		mLayoutHide.setLayoutParams(mParams);
	}
	
	
	
	private void setPortraitView(List<View> views) {
		if (views.size() > mMaxNum) {
			//将底部Button增加mLayoutShow和mLayoutHide
			mLayoutShow = adjustPortraitView(mLayoutShow, 0, mMaxNum - 1, views, true);
			mLayoutHide = adjustPortraitView(mLayoutHide, mMaxNum - 1, views.size(), views, false);
		} else {
			//假设底部图标数比較少,那么mLayoutHide就永远隐藏
			mLayoutHide.setVisibility(View.GONE);
			mLayoutShow = adjustPortraitView(mLayoutShow, 0, views.size(), views, false);
		}
	}
	
	private LinearLayout adjustPortraitView(LinearLayout layout, int start, int end, List<View> views, boolean isAddMore) {
		for (int i = start; i < end; i++) {
			final View view = views.get(i);
			view.setLayoutParams(new LayoutParams((int) mAverageSize, LayoutParams.FILL_PARENT));
			view.setTag(i);
			setClick(layout, view, LAUNCHER_BAR_LINE_ONE);
			layout.addView(view);
		}
		if (isAddMore) {
			mMoreView.setLayoutParams(new LayoutParams((int)mAverageSize, LayoutParams.FILL_PARENT));
			mLayoutShow.addView(mMoreView);
		}
		return layout;
	}
	
	private void setClick(final LinearLayout layout, final View view, final int line) {
		view.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				mRestart = false;
				if (onExpandItemClickListener != null) {
					onExpandItemClickListener.onExpandItemClick(layout, view, (Integer) view.getTag(), mMaxNum, line);
				}
			}
		});
	}
	
	
	public boolean isInAnimation() {
		return mIsInAnimation;
	}
	
	public boolean isCanMoveToBottom(){
		//这里依据getBottom来推断页面仅仅是展示mLayoutShow或是同一时候展示mLayoutShow和mLayoutHide
		//假设getBottom() < mOldBottom,这个时候就是页面仅仅有mlayoutShow,由于mLayoutShow和mLayoutHide同一时候存在时显然getBottom比較大
		if (mLayoutHide != null && mLayoutHide.getVisibility() == View.VISIBLE) {
			int bottom = this.getBottom();
			if (bottom > mOldBottom) {
				mCanMoveToBottom = false;
			} else if(bottom <= mOldBottom) {
				mCanMoveToBottom = true;
			}
		}
		return mCanMoveToBottom;
	}
	
	public void excuteAnimation(boolean isClickMore) {
		if (mLayoutHide != null && mLayoutHide.getVisibility() == View.VISIBLE) {
			if (!mIsInAnimation) {
				if (isCanMoveToBottom()) {
					mIsInAnimation = true;
					mMoreView.setSelected(false);
					//这个动画是向下的
					this.startAnimation(getAnimation(true, 0, 0, 0, mButtonHeight));
					mCanMoveToBottom = false;
				} else {
					if (isClickMore) {
						mIsInAnimation = true;
						mMoreView.setSelected(true);
						//这个动画是向上的
						this.startAnimation(getAnimation(false, 0, 0, 0, -mButtonHeight));
						mCanMoveToBottom = true;
					}
				}
			}
		}
	}
	
	private Animation getAnimation(final boolean moToBottom, int fromXDelta, final int toXDelta,
			int fromYDelta, final int toYDelta) {
		TranslateAnimation animation = new TranslateAnimation(fromXDelta,
				toXDelta, fromYDelta, toYDelta);
		animation.setDuration(200);
		animation.setFillAfter(true);
		animation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				ExpandableView.this.clearAnimation();
				ExpandableView.this.layout(ExpandableView.this.getLeft(),
						(ExpandableView.this.getTop() + toYDelta),
						ExpandableView.this.getRight(),
						(ExpandableView.this.getBottom() + toYDelta));
				mIsInAnimation = false;
			}
		});
		return animation;
	}
	
	public void setOnExpandItemClickListener(ExpandItemClickListener listener) {
		onExpandItemClickListener = listener;
	}

	public interface ExpandItemClickListener {
		void onExpandItemClick(final View parentView, View view, int position, int maxNum, int line);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (mLayoutHide != null && mLayoutHide.getVisibility() == View.VISIBLE) {
			if(mIsFirstLayout && this.getWidth() > 0){
				mIsFirstLayout = false;
				mOldBottom = this.getBottom();
				this.layout(this.getLeft(), (this.getTop() + mHeaderHeight), this.getRight(), (this.getBottom() + mHeaderHeight));
			}
			//假设是第一次显示该view,mLayoutHide是不显示的
			if (mRestart && this.getBottom() <= mOldBottom && !mIsFirstLayout) {
				this.layout(this.getLeft(), (this.getTop() + mHeaderHeight), this.getRight(), (this.getBottom() + mHeaderHeight));
			}
		}
	}
	
	public void setRestart(boolean restart){
		mRestart = restart;
	}
	
}

代码:http://download.csdn.net/download/baidu_nod/7748987

一个带动画的页面底部的TabBar的实现

标签:

原文地址:http://www.cnblogs.com/bhlsheji/p/5116982.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!