一个带动画的页面底部的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 ...
随机推荐
- Node-Webkit作者王文睿:桌面应用的全新开发方式
摘要:最近两年,Node.js技术越来越火,基于它所开发的应用也纷纷出现在大家面前,其中Node-Webkit就是这样的一个开源框架,它允许开发者使用Web技术开发桌面应用. Node-Webkit是 ...
- OpenStack优先
http://www.lagou.com/jobs/1623064.html http://www.lagou.com/jobs/1406144.html
- VC/MFC 工具栏上动态添加组合框等控件的方法
引言 工具条作为大多数标准的Windows应用程序的一个重要组成部分,使其成为促进人机界面友好的一个重要工具.通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开发 ...
- win32 sdk树形控件的项拖拽实现
本课中,我们将学习如何使用树型视图控件.另外还要学习如何在树型视图中完成拖-拉动作,以及如何使用图象列表. 理论: 树型视图是一种特别的窗口,我们可以使用它一目了然地表示某种层次关系.譬如象在资源管理 ...
- Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)
原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(二) 4.3 表达式用户搜索,只会输入一个或几个词,也可能是一句话.输入的语句是如何变成搜索条件的上一篇已经略有提及. 4.3.1 观察 ...
- tc3162目录
lsbin dev lib proc tmp usrboaroot etc linuxrc sbin userfs var# ...
- 【Demo 0004】屏幕、窗体及视图基础知识
本章学习要点 1. 了解iOS中应用程序(UIApplication)与屏幕.窗体以及视图相关基础知识: 2. 掌握应用程序常用的属性与方法: 3. 掌握窗 ...
- 重拾linux
重拾linux 起因 因为想重拾起linux,同时需要用docker起几个镜像,用来学习网络知识.本来想直接去阿里云上买,后来一想自己机器上,起一个linux是个不错的选择,毕竟不花钱! 还可以用来做 ...
- Java中替代C# ref/out 关键字方案:
刚学习Java不久,今天遇到一个问题,需要在方法中修改传入的对象的值,确切的说是需要使用一个方法,创建一个对象,并把其引用返回,熟悉C#的我的第一反应就是C#中的ref/out关键字,结果发现Java ...
- 【PostgreSQL】PostgreSQL语法
在阅读的过程中有不论什么问题.欢迎一起交流 邮箱:1494713801@qq.com QQ:1494713801 一.PostgreSQL时间类型转换 --时间类型转成字符类型 select t ...