本文由manymore13原创,转载请标明出处 http://blog.csdn.net/manymore13/article/details/12799061
本次我要向大家介绍一个Android特效,这个特效也是我在某款软件中看到的,至于软件叫什么,我今天就不说
它的名字。我就不免费为它做广告了。
好了,我来上一张动态效果图 在下面,屏幕小的请往下拉。
我不知道原软件是怎么个实现法,在这里我只是说说我的实现方法,代码可能不太好,这只是本人的一个idea 原理很简单!
特效实现原理:
改变按钮的宽度,每次当你点击按钮时,只有两个按钮改变宽度,一个变长,一个变短,只是这个变化是慢慢
进行,不是秒变的,你懂的,这就是动画效果。你点击短的按钮后会渐渐地变长,长的按钮会随着被压缩,其他按钮宽度不变。
我写这篇文章想起到一个抛砖引玉的效果,希望读者看了这篇文章后继续写个更好的文章。当然你不要忘记我啊,
记得要与我和大家分享。
下面是本次Demo运行后的效果图:
可以看到view被挤压的效果,点击短的view会慢慢长大。在短的view慢慢长大的同时,最长的view会慢慢缩小,而且每次动画结束后都
有一个最长的view 。我这里所说的view在本次Demo中是按钮,当然你也可以换成其他的控件,或者是ViewGroup的子类也行。
public class PinchActivity extends Activity implements View.OnClickListener { private final static String TAG = "MainActivity"; // 屏幕宽度 private int screentWidth = 0; // View可伸展最长的宽度 private int maxWidth; // View可伸展最小宽度 private int minWidth; // 当前点击的View private View currentView; // 显示最长的那个View private View preView; // 主布局ViewGroup private LinearLayout mainContain; // 标识符 动画是否结束 private boolean animationIsEnd = true; // 变大操作 private static final int OPE_BIG = 1; // 变小操作 private static final int OPE_SMALL = 2; // 当前操作 -1表示无效操作 private int currentOpe = -1; // 前进的步伐距离 private static final int STEP = 10; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initCommonData(); initViewData(); measureWidth(screentWidth); } private void initViewData() { mainContain = (LinearLayout) this.findViewById(R.id.main_contain); View child; int childCount = mainContain.getChildCount(); for (int i = 0; i < childCount; i++) { child = mainContain.getChildAt(i); child.setOnClickListener(this); } } private void initCommonData() { DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); screentWidth = metric.widthPixels; // 屏幕宽度(像素) } private void setCurrentViewParams() { if (currentView == null) { return; } LayoutParams params = currentView.getLayoutParams(); if (params == null) { return; } int realWidth = params.width; int nextWidth = 0; if (currentOpe == OPE_BIG) { nextWidth = realWidth + STEP; } else if (currentOpe == OPE_SMALL) { nextWidth = realWidth - STEP; } if (nextWidth > maxWidth) { nextWidth = maxWidth; } else if (nextWidth < minWidth) { nextWidth = minWidth; } params.width = nextWidth; currentView.setLayoutParams(params); if (nextWidth == maxWidth || nextWidth == minWidth) { animationIsEnd = true; onOffClickable(); stopAnimation(); return; } mHandler.sendEmptyMessageDelayed(1, 20); } // 初始化宽度 测量max min 长度 private void measureWidth(int screenWidth) { int halfWidth = screenWidth / 2; maxWidth = halfWidth - 50; minWidth = (screenWidth - maxWidth) / (mainContain.getChildCount() - 1); View child; int childCount = mainContain.getChildCount(); for (int i = 0; i < childCount; i++) { child = mainContain.getChildAt(i); LayoutParams params = child.getLayoutParams(); if (i == 0) { preView = child; params.width = maxWidth; } else { params.width = minWidth; } child.setLayoutParams(params); } } // 这里用handler更新界面 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 1) { setCurrentViewParams(); } } }; // 停止动画 private void stopAnimation() { currentOpe = -1; currentView = null; } private void startAnimation() { if (currentView == null || currentOpe == -1) { Log.d(TAG, "无效动画"); return; } animationIsEnd = false; onOffClickable(); mHandler.sendEmptyMessage(1); } @Override public void onClick(View v) { int id = v.getId(); switch (id) { case R.id.btnOne: currentView = mainContain.getChildAt(0); break; case R.id.btnTwo: currentView = mainContain.getChildAt(1); break; case R.id.btnThree: currentView = mainContain.getChildAt(2); break; case R.id.btnFour: currentView = mainContain.getChildAt(3); break; } Log.i(TAG, ((Button) currentView).getText().toString() + " click"); if (currentView != null && animationIsEnd) { int currentViewWidth = currentView.getWidth(); if (currentViewWidth == maxWidth) { currentOpe = OPE_SMALL; } else { currentOpe = OPE_BIG; } clickEvent(currentView); startAnimation(); } } private void clickEvent(View view) { View child; int childCount = mainContain.getChildCount(); for (int i = 0; i < childCount; i++) { child = mainContain.getChildAt(i); if (preView == child) { LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child .getLayoutParams(); params.weight = 1.0f; child.setLayoutParams(params); } else { LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child .getLayoutParams(); params.weight = 0.0f; params.width = minWidth; child.setLayoutParams(params); } } preView = view; printWeight(); } private void printWeight() { View child; int childCount = mainContain.getChildCount(); for (int i = 0; i < childCount; i++) { child = mainContain.getChildAt(i); LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child .getLayoutParams(); Log.i("mm1", ((Button) child).getText() + ": " + params.weight); } } // private void onOffClickable() { View child; boolean clickable = animationIsEnd; int childCount = mainContain.getChildCount(); for (int i = 0; i < childCount; i++) { child = mainContain.getChildAt(i); child.setClickable(clickable); } } }
改变控件的宽度或者高度:
1.获取参数类 LayoutParams params = View.getLayoutParams()
2. 设置控件高度或者宽度属性 params.width 、params.height
3.设置完属性后不要忘记 view.setLayoutParams(params);
LayoutParams 这个类是根据你父控件来获取的,比如我代码中:
LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child.getLayoutParams();
child是一个Button ,在XML中它的父控件是LinearLayout,所以我这里有上面的强转, LinearLayout.LayoutParams 不仅有设置控件宽度和高度的属性,还有一个本次Demo重点用到的一个属性android:layout_weight ,想必大家在开发中用到这个属性的不在少数吧!
android:layout_weight
Indicates how much of the extra space in the LinearLayout will be allocated to the view associated with these LayoutParams. Specify 0 if the view should not be stretched. Otherwise the extra pixels will be pro-rated among all views whose weight is greater than 0.
大概意思是View根据比例享用多余空间。这个比例就是你设置的这个值的大小,如果你设置它的值为0的话,就等于你没设置这个值,不等于零的话,就按你设的比例来瓜分LinearLayout中的多余空间。具体用法有不懂的请去seach。
最后说一些本次Demo中主要有以下三点不足:
1. 特效动画死板,变化速度死板;
2. 特效动画不能设置动画时间,如遇到高分辨率的机型,动画时间会变长。
3. view只能水平伸缩,不能竖直伸缩。
以上三点不足将在下篇为大家解决。
好了,上述就是本次特效讲解的全部内容,有什么地方说的有误的,欢迎您指正!欢迎拍砖!欢迎留言,如对你有帮助,请不要吝惜你手中的鼠标左键,点赞一个!
这篇看完了可以继续看我的下一篇 Android特效开发(可伸缩View带互相挤压效果)进阶篇
Demo源码