一个带动画的页面底部的TabBar的实现
有时有这样一个需求,页面底部有几个图标能够点击,假设一个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