- 浏览: 707447 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
葫芦瓢:
葫芦瓢 写道专注IT 写道请问楼主demo中为什么是Custo ...
Android Scroller简单用法 -
葫芦瓢:
专注IT 写道请问楼主demo中为什么是CustomView中 ...
Android Scroller简单用法 -
u011493452:
注册账号给楼主点赞!
Android Scroller简单用法 -
jiduoduo:
整理的不错!
Android文件存储 -
xiaofeng0817166:
http://deerchao.net/tutorials/r ...
Java正则表达式应用
参考博客http://yanweimin7.iteye.com/blog/1126570 实现,把mNowRect的更新放到Handler里,逻辑更简单。
实现效果如下图:在“首页”和“我的信息”之间切换时,后面的背景从“首页”以动画形式滚动到“我的信息”。
思路:自定义一个控件MoveTab,继承LinearLayout。假设当前选中的控件区域为mNowRect,目标控件区域为mEndRect。我们还需要一个Drawable mDrawable(就是切换过程中移动的图片)。使用Handler更新mNowRect,重写onDraw(),在onDraw()里将Drawable画在mEndRect里,直到mNowRect和mEndRect重合。
因为这里的mDrawable和MoveTab相关性比较大,为了使MoveTab更加通用,我们还使用了attrs.xml,并在其中定义属性move_drawable,和mDrawable相关联。
res/values/attrs.xml
在res/layout/main.xml中定义MoveTab时,可以通过下面xml代码指定mDrawable
在布局文件main.xml中,我们使用<com.ipjmc.demo.view.MoveTab></com.ipjmc.demo.view.MoveTab>来指定MoveTab,并在其中添加了5个Button,在外观上和新浪微博的一样
res/layout/main.xml
MoveTab的定义,具体代码如下:
MoveDrawableActivity.java 文件
全部代码请查看附件
实现效果如下图:在“首页”和“我的信息”之间切换时,后面的背景从“首页”以动画形式滚动到“我的信息”。
思路:自定义一个控件MoveTab,继承LinearLayout。假设当前选中的控件区域为mNowRect,目标控件区域为mEndRect。我们还需要一个Drawable mDrawable(就是切换过程中移动的图片)。使用Handler更新mNowRect,重写onDraw(),在onDraw()里将Drawable画在mEndRect里,直到mNowRect和mEndRect重合。
因为这里的mDrawable和MoveTab相关性比较大,为了使MoveTab更加通用,我们还使用了attrs.xml,并在其中定义属性move_drawable,和mDrawable相关联。
res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MoveTab"> <attr name="move_drawable" format="reference" /> </declare-styleable> </resources>
在res/layout/main.xml中定义MoveTab时,可以通过下面xml代码指定mDrawable
xmlns:demo="http://schemas.android.com/apk/res/com.ipjmc.demo" ... demo:move_drawable="@drawable/home_btn_bg_d" <!--指定mDrawable-->
在布局文件main.xml中,我们使用<com.ipjmc.demo.view.MoveTab></com.ipjmc.demo.view.MoveTab>来指定MoveTab,并在其中添加了5个Button,在外观上和新浪微博的一样
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:demo="http://schemas.android.com/apk/res/com.ipjmc.demo" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:text="@string/hello" android:layout_width="fill_parent" android:layout_height="0px" android:layout_weight="1"/> <com.ipjmc.demo.view.MoveTab android:id="@+id/move_tab" android:background="@drawable/home_btn_bg_n" android:orientation="horizontal" demo:move_drawable="@drawable/home_btn_bg_d" android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:tag="radio_button0" android:text="@string/main_home" android:drawableTop="@drawable/icon_home" style="@style/main_tab_bottom" /> <Button android:tag="radio_button1" android:text="@string/main_news" android:drawableTop="@drawable/icon_meassage" style="@style/main_tab_bottom" /> <Button android:tag="radio_button2" android:text="@string/main_my_info" android:drawableTop="@drawable/icon_selfinfo" style="@style/main_tab_bottom" /> <Button android:tag="radio_button3" android:text="@string/menu_search" android:drawableTop="@drawable/icon_square" style="@style/main_tab_bottom" /> <Button android:tag="radio_button4" android:text="@string/more" android:drawableTop="@drawable/icon_more" style="@style/main_tab_bottom" /> </com.ipjmc.demo.view.MoveTab> </LinearLayout>
MoveTab的定义,具体代码如下:
package com.ipjmc.demo.view; import com.ipjmc.demo.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.LinearLayout; public class MoveTab extends LinearLayout { private static final int DELAY = 10; private static final int SPEED = 16; private static final int MOVE = 1; private static final String TAG = "MoveTab"; private Context mContext; private Drawable mDrawable;//移动的背景图 private final Rect mNowRect = new Rect();//当前的区域 private final Rect mEndRect = new Rect();//结束的区域 private final Handler mHandler = new Handler() { public void handleMessage(Message msg) { if (msg.what == MOVE) { //如果还没有到达目标区域,就延迟DELAY后,重新绘图 if (!move()) { this.sendEmptyMessageDelayed(MOVE, DELAY); } } }; }; public MoveTab(Context context) { super(context); init(context, null); } public MoveTab(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } private void init(Context context, AttributeSet attrs) { mContext = context; TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.MoveTab); //通过XML中定义的属性"move_drawable",生成mDrawable mDrawable = attr.getDrawable(R.styleable.MoveTab_move_drawable); if (mDrawable == null) { Log.e(TAG, "Errorr : mDrawable == null"); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //默认选择第一个table,把它的区域设置为mNowRect this.getChildAt(0).getHitRect(mNowRect); super.onLayout(changed, l, t, r, b); } /** * 对外公开的接口,外部调用者应该在table被点击时调用它,将mDrawable移动到目标控件v * @param 目标控件 */ public void selectTab(View v) { //将目标控件v的区域设置为mEndRect v.getHitRect(mEndRect); if (mNowRect.right != mEndRect.right) { mHandler.sendEmptyMessage(MOVE); //向Handler发送消息,开始移动mDrawable } } /** * 重新计算图片的位置 * @return 动画是否结束 */ private boolean move() { int direction = 0; //已非常接近目标控件, 直接让mNowRect和mEndRect重合 if (Math.abs(mNowRect.left - mEndRect.left) <= SPEED) { mNowRect.left = mEndRect.left; mNowRect.right = mEndRect.right; invalidate(); return true; } if (mNowRect.left < mEndRect.left) { direction = 1; //向右 } else { direction = -1; //向左 } //更新mNowRect mNowRect.left += SPEED * direction; mNowRect.right += SPEED * direction; //请求onDraw() invalidate(); return false; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (null != mDrawable) { //将mDrawable画到mNowRect上 mDrawable.setBounds(mNowRect); mDrawable.draw(canvas); Log.i(TAG, "onDraw : " + mNowRect.left + ", " + mNowRect.right + ", " + mNowRect.top + ", " + mNowRect.bottom); } else { Log.e(TAG, "Errorr : mDrawable == null"); } } }
MoveDrawableActivity.java 文件
package com.ipjmc.demo; import com.ipjmc.demo.view.MoveTab; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; import android.widget.RadioGroup; public class MoveDrawableActivity extends Activity implements OnClickListener{ private static final String TAG = "MoveTab"; private RadioGroup mRadioGroup; private Button mButton[]; private MoveTab mMoveTab; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "onCreate"); setContentView(R.layout.main); mMoveTab = (MoveTab) findViewById(R.id.move_tab); initRadios(); } private void initRadios() { mButton = new Button[5]; String tag = "radio_button"; for (int i = 0; i < mButton.length; i++) { mButton[i] = (Button) mMoveTab.findViewWithTag(tag+i); //通过tag查找View mButton[i].setOnClickListener(this); } } @Override public void onClick(View v) { //点击后,开始动画 mMoveTab.selectTab(v); } }
全部代码请查看附件
发表评论
-
Android Notification的使用
2012-10-20 19:28 9777Android 4.1 (Jelly Bean ... -
短信拦截
2012-09-25 20:40 2091最近写一个应用(A),需要拦截短信分析。一般是 ... -
Android Scroller简单用法
2012-08-01 16:35 65890Android里Scroller类是为了实现Vi ... -
Android 使用WebView.loadData中文乱码解决办法
2012-07-19 15:09 9600博主在使用WebView的loadData方法时发 ... -
Android HttpClient基本使用方法
2012-07-05 14:15 107898这里只介绍如何使用HttpClient发起GET或者POST请 ... -
Android XML定义颜色
2012-06-09 13:15 0在res/colors.xml中添加如下代码: 定义C ... -
Activity和Task的设计思路和方法
2012-03-29 20:20 1257Activity和 Task是 Android ... -
显示PopupWindow
2012-03-16 10:04 16677PopupWindow可 ... -
存储文件的ContentProvider
2012-03-08 23:37 9412基于SQLite的ContentProvider ... -
Android文件存储
2012-03-08 22:34 19477Internal Storage内部存储空 ... -
Android 使用Notification
2012-03-07 10:26 2244用惯了Android的人在刚拿到iPhone的 ... -
Android用软键盘将整个界面推上去
2012-03-04 17:11 35903在Android UI中 ... -
onInterceptTouchEvent和onTouchEvent调用时序
2012-02-11 23:42 1071onInterceptTouchEvent() ... -
使用ConnectivityManager监听网络状态变化
2011-12-24 11:16 29857mIntenFilter = new IntentFilte ... -
Window Manager
2012-03-22 23:51 1557Android的窗口机制基于WindowManager,可以通 ... -
CommonsWare Android Components
2011-12-17 16:10 1765CommonsWare Android Com ... -
Android中图片缩放
2011-12-17 00:09 1931下载的图片如果过大,可能导致内存溢出。需要做压 ... -
Android 使用Parcelable序列化对象
2011-12-16 23:43 36603Android序列化对象主要有两种方法,实现S ... -
PreferenceActivity
2011-12-12 22:54 922传送门:http://www.cnblogs.com/wser ... -
View.scrollBy()与View.scrollTo()的使用
2011-12-12 22:40 19611scrollTo()和scrollBy()都是V ...
相关推荐
通过上述步骤,你就能实现类似QQ2012 TableHost的左右切换动画效果。记得在实际开发中根据需求调整动画时长、动画类型以及触发切换的条件,以达到最佳的用户体验。在项目中使用TableFlipperExample这个示例代码,...
在Android开发中,"ExpandTable"是一个常见的需求,特别是在构建类似58同城这样的信息分类列表时,用户可能需要点击一个条目来展开更多的详细信息。这个项目实现了这种点击展开的效果,利用了Android的基础布局组件`...
4. **国际化与适配**:smartTable支持多语言切换,只需提供不同的语言资源文件。同时,根据屏幕尺寸和方向进行适配,保证在不同设备上的良好显示效果。 五、总结 smartTable作为一款优秀的Android表格框架,其强大...
在Android开发中,TableHost控件可能并非标准的Android SDK内置控件,但根据标题和描述,我们可以推测这里提到的TableHost可能是开发者自定义或者是一个特定库提供的组件,用于实现类似表格布局或视图切换的功能。...
这个资源专注于利用`ViewPager`和`Fragment`来构建这样的界面,这两种组件是Android SDK中的核心组件,用于实现动态和交互性强的用户界面。接下来,我们将深入探讨这两个组件以及如何结合使用它们来创建一个仿微信的...
7. CoordinatorLayout:这是一种高级布局,用于实现复杂的交互和动画效果,如滑动隐藏顶部栏或底部导航栏。它利用布局行为(Layout Behaviors)使子视图能够响应触摸事件或系统状态改变。 8. ConstraintLayout:这...
第1章 Android的系统介绍5 1.1 系统介绍5 1.2 软件结构和使用的工具7 第2章 Android SDK的开发环境10 2.1 Android SDK的结构10 2.2 Android SDK环境安装11 2.2.1. 安装JDK基本Java环境11 ...10.4 3D动画效果的实现129
9. **栈布局(StackView/ViewSwitcher)**:这类布局常用于实现滑动切换效果,如卡片堆叠,可以包含多个子视图,一次只显示一个。 10. **螺旋布局(Gallery)**:已弃用的布局,以前用于创建轮播效果,现在可以使用...
此外,还可以使用`FragmentTransaction`的`setCustomAnimations()`方法为不同页面间的切换添加动画效果。 以上四个知识点在Android应用开发中扮演着核心角色,理解并熟练运用它们能够提升应用的用户体验和性能。在...
3. **SQLite数据库操作**:要实现备忘录的增删查改功能,需要编写SQL语句,包括CREATE TABLE用于创建数据库表,INSERT INTO用于添加新备忘,SELECT查询备忘,UPDATE更新已有备忘,以及DELETE删除备忘。 4. **...
**横竖屏切换不销毁当前Activity**:在AndroidManifest.xml中为对应的Activity设置`android:configChanges="orientation|screenSize"`属性即可。 ##### 2.2 INTENTRECEIVER `IntentReceiver`是用于接收系统或其他...
- **Tween动画**:这类动画通过修改视图的属性来实现平滑的过渡效果,如位置、大小、透明度等。适用于实现较为简单的视觉效果,如淡入淡出、缩放等。 - **Frame动画**:Frame动画通过连续播放一系列预先准备好的帧...
同时,随着Android版本的更新,新的布局工具和特性不断出现,如`ConstraintLayout`的`MotionLayout`扩展,使动态动画设计变得更加简单。 总之,理解并熟练掌握Android的各种布局方式是创建高效、美观且适应性强的...
1. **Tween动画**:这种动画通过改变视图组件的位置、大小和透明度等属性来实现动画效果,而无需重新绘制图像。适用于简单的动画效果,如淡入淡出、缩放等。 2. **Frame动画**:这种动画类似于电影播放,通过连续...
它常用于实现动画效果,与Fragment一起使用。 4. **PercentFrame/RelativeLayout**:百分比布局允许开发者基于父布局的百分比来设置控件的大小,避免了硬编码尺寸的问题,实现灵活的平分布局。使用前需要添加对应的...
1. **侧滑导航(Slide Navigation)**:在移动应用设计中,侧滑菜单通常用于实现主界面与导航菜单之间的切换,提供一种简洁的多层级导航方式。在这个例子中,开发者可能使用了Android的SlidingDrawer或Navigation...
综上所述,"底布突起导航栏"的实现涉及到多个Android开发技术,包括自定义视图、布局设计、事件处理、动画效果、图标更换、Fragment切换、设备适配和触摸反馈等。通过掌握这些技术,开发者可以创建出符合设计需求且...
1. **重写测量和布局**:为了实现可循环滚动,`ForeverLayout`需要知道所有子视图的大小和位置,以便在滚动到边界时能够无缝切换到下一个或上一个元素。这涉及到对`onMeasure()`和`onLayout()`方法的重写。 2. **...