一个带动画的页面底部的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;
} }
一个带动画的页面底部的TabBar的实现的更多相关文章
- 收藏一个带动画效果的ScrollViewer以及ScrollBar的模板
这里介绍一个带动画效果的ScrollViewer和ScrollBar,总共分为两个资源字典,直接拿来引用即可: 1 ScrollBarStyle.xaml <ResourceDictionary ...
- 利用css transition属性实现一个带动画显隐的微信小程序部件
我们先来看效果图 像这样的一个带过渡效果的小部件在我们实际开发中的应用几率还是比较大的,但是在开发微信小程序的过程中可能有的小伙伴发现transition这个属性它不好使(下面说明)所以我们这个时候会 ...
- iOS使用push隐藏子页面底部bottom TabBar
下面两种情况是我在开发过程中遇到的,一种是代码使用pushViewController,还有一种是storyboard直接使用push.之前也查阅了非常多关于隐藏底部tabbar的资料.可是要么使用起 ...
- IOS的一个带动画的多项选择的控件(一)
先上效果图: 这个程序分2个层次,一个是顶部的带UITextField的bar,一个是下拉选择的view,下拉选择的view带有4个自己定义的UIView 我们先定义一个UIViewControlle ...
- 一个带动画效果的颜色选择对话框控件AnimatedColorPickerDialog
android4.4的日历中选择日程显示颜色的时候有一个颜色选择对话框非常漂亮,模仿他的界面我实现了一个类似的对话框,而且带有动画效果. 代码的实现可讲的地方不多,主要是采用了和AlertDialog ...
- 兼容IE6的页面底部固定层CSS代码
有时候当我们需要把一个元素固定在页面的某个部位,一般都是用css中的“position:fixed;”方法来解决,但是IE6不支持fixed,所以今天分享一个兼容IE6的页面底部固定层CSS代码.如下 ...
- Android开发:带动画的分享效果
这几天做了个带动画的分享页面.如今把它分享出来,假设你认为实用,请直接使用,避免反复造轮子 先看下效果图 认为仅仅是看效果图不明显.那么用手机扫描以下的二维码下载安装包:
- jquery插件——点击交换元素位置(带动画效果)
一.需求的诞生 在我们的网页或者web应用中,想要对列表中的元素进行位置调整(或者说排序)是一个常见的需求.实现方式大概就以下两种,一种是带有类似“上移”.“下移”的按钮,点击可与相邻元素交换位置,另 ...
- jQuery之锚点带动画跳转特效
背景图片为金木研,这是我最爱的一张图. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quo ...
随机推荐
- hadoop学习之ZooKeeper
1. 什么是ZooKeeper? ZooKeeper是一组工具,用来配置和支持分布式调度. 它能处理分布式应用的“部分失败”问题. 什么是部分失败? 部分失败是分布式处理系统的固有特征,即发送者无法知 ...
- DFA最小化 -- Hopcroft算法 Python实现
wiki 伪代码看上去一直以为怪.发现葡萄牙语和俄罗斯语那里的 if 推断都还缺少一个条件. 国内的资料比較少.这几份学习资料不错.比我稀里糊涂的思路要好,分享下: http://www.liafa. ...
- 积累的VC编程小技巧之图标、光标及位图
1.图标透明 (1).Windows中的图标其实是有两个图像组成的,其中一个用于与它要显示的位置的图像做“AND”操作,另一个作“XOR”操作. 透明:用“白色”AND,用“黑色”XOR 反色:用“白 ...
- objective-C 中的内存管理解说
初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏或莫名其妙的崩溃.我在这里总结了自己对objective-C内存管理机制的研究成果和 ...
- 【老鸟学算法】包含 min函数的栈设计——java实现
要求: 1. 定义栈的数据结构,要求添加一个 min函数,能够得到栈的最小元素. 2. 要求函数 min.push 以及 pop 的时间复杂度都是 O(1). 这是考验“栈”数据结构设计.众所周知,栈 ...
- 浅析innodb_support_xa与innodb_flush_log_at_trx_commit
很久以前对innodb_support_xa存在一点误解,当初一直认为innodb_support_xa只控制外部xa事务,内部的xa事务是mysql内部进行控制,无法人为干预(这里说的内部xa事务主 ...
- 再说Java EE
说到JavaEE(曾经叫J2EE)是什么,你可能回答:JavaEE是一组规范,这么说是没错,可是自己不认为这个答案非常大.非常空么?什么又是规范?规范能组成应用么?能在JVM中跑起来么?要理解这些,先 ...
- 简单的RPC java实现
RPC的名声大噪之时是在2003年,那一个“冲击波”病毒(Blaster Worm virus)袭卷全球的一年.而“冲击波”正是用着RPC这把刀来敲开了远程电脑的大门.当然RPC 有更多正面的应用,比 ...
- thinkphp模版调用函数方法
原文:thinkphp模版调用函数方法 {变量|函数1|函数2|函数3=参数1,参数2,参数3,###} ###为第4个参数,代表变量替换为第4个参数 举例: {$username|substr=0, ...
- poj2299--B - Ultra-QuickSort(线段树,离散化)
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 41215 Accepted: 14915 ...