【转】android特效之可伸缩View带互相挤压效果-初级篇

【转】android特效之可伸缩View带互相挤压效果--初级篇

 

转自:http://blog.csdn.net/manymore13/article/details/12799061

本次我要向大家介绍一个Android特效,这个特效也是我在某款软件中看到的,至于软件叫什么,我今天就不说

它的名字。我就不免费为它做广告了。【转】android特效之可伸缩View带互相挤压效果-初级篇

好了,我来上一张动态效果图 在下面,屏幕小的请往下拉。

我不知道原软件是怎么个实现法,在这里我只是说说我的实现方法,代码可能不太好,这只是本人的一个idea 原理很简单!

      特效实现原理:

改变按钮的宽度,每次当你点击按钮时,只有两个按钮改变宽度,一个变长,一个变短,只是这个变化是慢慢

进行,不是秒变的,你懂的,这就是动画效果。你点击短的按钮后会渐渐地变长,长的按钮会随着被压缩,其他按钮宽度不变。

 

我写这篇文章想起到一个抛砖引玉的效果,希望读者看了这篇文章后继续写个更好的文章。当然你不要忘记我啊,

记得要与我和大家分享。

 

 下面是本次Demo运行后的效果图:

 

【转】android特效之可伸缩View带互相挤压效果-初级篇

可以看到view被挤压的效果,点击短的view会慢慢长大。在短的view慢慢长大的同时,最长的view会慢慢缩小,而且每次动画结束后都

有一个最长的view 。我这里所说的view在本次Demo中是按钮,当然你也可以换成其他的控件,或者是ViewGroup的子类也行。

 

[java] view plaincopyprint?
  1. public class PinchActivity extends Activity implements View.OnClickListener {  
  2.   
  3.     private final static String TAG = "MainActivity";  
  4.       
  5.     // 屏幕宽度  
  6.     private int screentWidth = 0;  
  7.       
  8.     // View可伸展最长的宽度  
  9.     private int maxWidth;  
  10.       
  11.     // View可伸展最小宽度  
  12.     private int minWidth;  
  13.       
  14.     // 当前点击的View  
  15.     private View currentView;  
  16.       
  17.     // 显示最长的那个View  
  18.     private View preView;  
  19.       
  20.     // 主布局ViewGroup  
  21.     private LinearLayout mainContain;  
  22.       
  23.     // 标识符 动画是否结束  
  24.     private boolean animationIsEnd = true;  
  25.       
  26.     // 变大操作  
  27.     private static final int OPE_BIG = 1;  
  28.       
  29.     // 变小操作  
  30.     private static final int OPE_SMALL = 2;  
  31.       
  32.     // 当前操作 -1表示无效操作  
  33.     private int currentOpe = -1;  
  34.       
  35.     // 前进的步伐距离  
  36.     private static final int STEP = 10;  
  37.   
  38.     @Override  
  39.     protected void onCreate(Bundle savedInstanceState)   
  40.     {  
  41.   
  42.         super.onCreate(savedInstanceState);  
  43.           
  44.         setContentView(R.layout.activity_main);  
  45.   
  46.         initCommonData();  
  47.           
  48.         initViewData();  
  49.           
  50.         measureWidth(screentWidth);   
  51.   
  52.     }  
  53.   
  54.     private void initViewData() {  
  55.   
  56.         mainContain = (LinearLayout) this.findViewById(R.id.main_contain);  
  57.         View child;  
  58.         int childCount = mainContain.getChildCount();  
  59.         for (int i = 0; i < childCount; i++) {  
  60.             child = mainContain.getChildAt(i);  
  61.             child.setOnClickListener(this);  
  62.         }  
  63.     }  
  64.       
  65.     private void initCommonData()  
  66.     {  
  67.         DisplayMetrics metric = new DisplayMetrics();  
  68.         getWindowManager().getDefaultDisplay().getMetrics(metric);  
  69.         screentWidth = metric.widthPixels; // 屏幕宽度(像素)  
  70.     }  
  71.   
  72.   
  73.     private void setCurrentViewParams() {  
  74.   
  75.         if (currentView == null) {  
  76.             return;  
  77.         }  
  78.         LayoutParams params = currentView.getLayoutParams();  
  79.         if (params == null) {  
  80.             return;  
  81.         }  
  82.         int realWidth = params.width;  
  83.         int nextWidth = 0;  
  84.         if (currentOpe == OPE_BIG) {  
  85.             nextWidth = realWidth + STEP;  
  86.         } else if (currentOpe == OPE_SMALL) {  
  87.             nextWidth = realWidth - STEP;  
  88.         }  
  89.         if (nextWidth > maxWidth) {  
  90.             nextWidth = maxWidth;  
  91.         } else if (nextWidth < minWidth) {  
  92.             nextWidth = minWidth;  
  93.         }  
  94.         params.width = nextWidth;  
  95.         currentView.setLayoutParams(params);  
  96.         if (nextWidth == maxWidth || nextWidth == minWidth) {  
  97.             animationIsEnd = true;  
  98.             onOffClickable();  
  99.             stopAnimation();  
  100.             return;  
  101.         }  
  102.         mHandler.sendEmptyMessageDelayed(120);  
  103.     }  
  104.   
  105.     // 初始化宽度 测量max min 长度  
  106.     private void measureWidth(int screenWidth) {  
  107.           
  108.         int halfWidth = screenWidth / 2;  
  109.         maxWidth = halfWidth - 50;  
  110.         minWidth = (screenWidth - maxWidth) / (mainContain.getChildCount() - 1);  
  111.   
  112.         View child;  
  113.         int childCount = mainContain.getChildCount();  
  114.         for (int i = 0; i < childCount; i++) {  
  115.             child = mainContain.getChildAt(i);  
  116.             LayoutParams params = child.getLayoutParams();  
  117.             if (i == 0) {  
  118.                 preView = child;  
  119.                 params.width = maxWidth;  
  120.             } else {  
  121.                 params.width = minWidth;  
  122.             }  
  123.   
  124.             child.setLayoutParams(params);  
  125.         }  
  126.     }  
  127.   
  128.     // 这里用handler更新界面  
  129.     private Handler mHandler = new Handler() {  
  130.   
  131.         @Override  
  132.         public void handleMessage(Message msg) {  
  133.   
  134.             if (msg.what == 1) {  
  135.                 setCurrentViewParams();  
  136.             }   
  137.         }  
  138.   
  139.     };  
  140.   
  141.     // 停止动画  
  142.     private void stopAnimation() {  
  143.         currentOpe = -1;  
  144.         currentView = null;  
  145.     }  
  146.   
  147.     private void startAnimation() {  
  148.   
  149.         if (currentView == null || currentOpe == -1) {  
  150.             Log.d(TAG, "无效动画");  
  151.             return;  
  152.         }  
  153.           
  154.         animationIsEnd = false;  
  155.         onOffClickable();  
  156.         mHandler.sendEmptyMessage(1);  
  157.     }  
  158.   
  159.     @Override  
  160.     public void onClick(View v) {  
  161.           
  162.         int id = v.getId();  
  163.           
  164.         switch (id) {  
  165.           
  166.         case R.id.btnOne:  
  167.             currentView = mainContain.getChildAt(0);  
  168.             break;  
  169.         case R.id.btnTwo:  
  170.             currentView = mainContain.getChildAt(1);  
  171.             break;  
  172.         case R.id.btnThree:  
  173.             currentView = mainContain.getChildAt(2);  
  174.             break;  
  175.         case R.id.btnFour:  
  176.             currentView = mainContain.getChildAt(3);  
  177.             break;  
  178.         }  
  179.   
  180.         Log.i(TAG, ((Button) currentView).getText().toString() + " click");  
  181.           
  182.         if (currentView != null && animationIsEnd) {  
  183.               
  184.             int currentViewWidth = currentView.getWidth();  
  185.               
  186.             if (currentViewWidth == maxWidth) {  
  187.                 currentOpe = OPE_SMALL;  
  188.             } else {  
  189.                 currentOpe = OPE_BIG;  
  190.             }  
  191.               
  192.             clickEvent(currentView);  
  193.               
  194.             startAnimation();  
  195.         }  
  196.   
  197.     }  
  198.   
  199.     private void clickEvent(View view) {  
  200.         View child;  
  201.         int childCount = mainContain.getChildCount();  
  202.         for (int i = 0; i < childCount; i++) {  
  203.             child = mainContain.getChildAt(i);  
  204.             if (preView == child) {  
  205.                 LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child  
  206.                         .getLayoutParams();  
  207.                 params.weight = 1.0f;  
  208.                 child.setLayoutParams(params);  
  209.             } else {  
  210.                 LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child  
  211.                         .getLayoutParams();  
  212.                 params.weight = 0.0f;  
  213.                 params.width = minWidth;  
  214.                 child.setLayoutParams(params);  
  215.             }  
  216.         }  
  217.         preView = view;  
  218.         printWeight();  
  219.     }  
  220.   
  221.     private void printWeight() {  
  222.         View child;  
  223.         int childCount = mainContain.getChildCount();  
  224.         for (int i = 0; i < childCount; i++) {  
  225.             child = mainContain.getChildAt(i);  
  226.             LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) child  
  227.                     .getLayoutParams();  
  228.             Log.i("mm1", ((Button) child).getText() + ": " + params.weight);  
  229.         }  
  230.     }  
  231.       
  232.     //   
  233.     private void onOffClickable()  
  234.     {  
  235.         View child;  
  236.         boolean clickable = animationIsEnd;  
  237.         int childCount = mainContain.getChildCount();  
  238.         for (int i = 0; i < childCount; i++) {  
  239.             child = mainContain.getChildAt(i);  
  240.             child.setClickable(clickable);  
  241.         }  
  242.     }  
  243.   
  244. }  

 

 

改变控件的宽度或者高度:

 1.获取参数类  LayoutParams params =  View.getLayoutParams()  

 2. 设置控件高度或者宽度属性 params.width 、params.height 

 3.设置完属性后不要忘记  view.setLayoutParams(params);

 

LayoutParams 这个类是根据你父控件来获取的,比如我代码中:

 

[java] view plaincopyprint?
  1. 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带互相挤压效果-初级篇