安卓中級教程(9):pathbutton中的animation.java研究(2)

  1 src/geniuz/myPathbutton/composerLayout.java
  2 
  3 package geniuz.myPathbutton;
  4 
  5 import com.nineoldandroids.animation.Animator;
  6 import com.nineoldandroids.animation.Animator.AnimatorListener;
  7 import com.nineoldandroids.view.ViewPropertyAnimator;
  8 
  9 import android.R;
 10 import android.annotation.SuppressLint;
 11 import android.content.Context;
 12 import android.graphics.Bitmap;
 13 import android.graphics.BitmapFactory;
 14 import android.util.AttributeSet;
 15 import android.view.View;
 16 import android.view.animation.ScaleAnimation;
 17 import android.widget.ImageView;
 18 import android.widget.LinearLayout;
 19 import android.widget.RelativeLayout;
 20 import static com.nineoldandroids.view.ViewPropertyAnimator.animate;
 21 
 22 @SuppressLint("ViewConstructor")
 23 public class composerLayout extends RelativeLayout {
 24 
 25     public static byte RIGHTBOTTOM = 1, CENTERBOTTOM = 2, LEFTBOTTOM = 3,
 26             LEFTCENTER = 4, LEFTTOP = 5, CENTERTOP = 6, RIGHTTOP = 7,
 27             RIGHTCENTER = 8;
 28     private boolean hasInit = false; // 初始化咗未
 29     private boolean areButtonsShowing = false;// 有冇展開
 30     private Context mycontext;
 31     private ImageView cross; // 主按鈕中間嗰個十字
 32     private RelativeLayout rlButton;// 主按鈕
 33     private myAnimations myani; // 動畫類
 34     private LinearLayout[] llayouts; // 子按鈕集
 35     private int duretime = 300;
 36 
 37     /**
 38      * 構造函數 本來想喺構造函數度讀取參數嘅,但就要喺values下面搞個attr,同埋layout嘅xml又要加命名空間————
 39      * 咁搞嘅話~好多人可能唔知點用,而且參數太多(例如N個子按鈕)處理起身亦比較羅嗦。
 40      * 所以而家乾脆搞個init()函數,由java代碼調用,唔讀xml喇。 所以構造函數只記錄個context就算
 41      */
 42     public composerLayout(Context context, AttributeSet attrs, int defStyle) {
 43         super(context, attrs, defStyle);
 44         this.mycontext = context;
 45     }
 46 
 47     public composerLayout(Context context, AttributeSet attrs) {
 48         super(context, attrs);
 49         this.mycontext = context;
 50     }
 51 
 52     public composerLayout(Context context) {
 53         super(context);
 54         this.mycontext = context;
 55     }
 56 
 57     /**
 58      * 初始化
 59      * 
 60      * @param imgResId
 61      *            子按鈕嘅圖片drawalbe嘅id[]
 62      * @param showhideButtonId
 63      *            主按鈕嘅圖片drawable嘅id
 64      * @param crossId
 65      *            主按鈕上面嗰個轉動十字嘅圖片drawable嘅id
 66      * @param pCode
 67      *            位置代碼,例如“右上角”係ALIGN_PARENT_BOTTOM|ALIGN_PARENT_RIGHT
 68      * @param radius
 69      *            半徑
 70      * @param durationMillis
 71      *            動畫耗時
 72      */
 73     public void init(int[] imgResId, int showhideButtonId, int crossId,
 74             byte pCode, int radius, final int durationMillis) {
 75         duretime = durationMillis;
 76         // 處理pcode,將自定義嘅位置值改成align值
 77         int align1 = 12, align2 = 14;
 78         if (pCode == RIGHTBOTTOM) { // 右下角
 79             align1 = ALIGN_PARENT_RIGHT;
 80             align2 = ALIGN_PARENT_BOTTOM;
 81         } else if (pCode == CENTERBOTTOM) {// 中下
 82             align1 = CENTER_HORIZONTAL;
 83             align2 = ALIGN_PARENT_BOTTOM;
 84         } else if (pCode == LEFTBOTTOM) { // 左下角
 85             align1 = ALIGN_PARENT_LEFT;
 86             align2 = ALIGN_PARENT_BOTTOM;
 87         } else if (pCode == LEFTCENTER) { // 左中
 88             align1 = ALIGN_PARENT_LEFT;
 89             align2 = CENTER_VERTICAL;
 90         } else if (pCode == LEFTTOP) { // 左上角
 91             align1 = ALIGN_PARENT_LEFT;
 92             align2 = ALIGN_PARENT_TOP;
 93         } else if (pCode == CENTERTOP) { // 中上
 94             align1 = CENTER_HORIZONTAL;
 95             align2 = ALIGN_PARENT_TOP;
 96         } else if (pCode == RIGHTTOP) { // 右上角
 97             align1 = ALIGN_PARENT_RIGHT;
 98             align2 = ALIGN_PARENT_TOP;
 99         } else if (pCode == RIGHTCENTER) { // 右中
100             align1 = ALIGN_PARENT_RIGHT;
101             align2 = CENTER_VERTICAL;
102         }
103         // 如果細過半徑就整大佢
104         RelativeLayout.LayoutParams thislps = (LayoutParams) this
105                 .getLayoutParams();
106         Bitmap mBottom = BitmapFactory.decodeResource(mycontext.getResources(),
107                 imgResId[0]);
108         if (pCode == CENTERBOTTOM || pCode == CENTERTOP) {
109             if (thislps.width != -1
110                     && thislps.width != -2
111                     && thislps.width < (radius + mBottom.getWidth() + radius * 0.1) * 2) {
112                 thislps.width = (int) ((radius * 1.1 + mBottom.getWidth()) * 2);
113             }
114         } else {
115             if (thislps.width != -1
116                     && thislps.width != -2
117                     && thislps.width < radius + mBottom.getWidth() + radius
118                             * 0.1) { // -1係FILL_PARENT,-2係WRAP_CONTENT
119                 // 因為animation嘅setInterpolator設咗OvershootInterpolator,即系喐到目標之後仍然行多一段(超過目標位置)~然後再縮返到目標位置,所以父layout就要再放大少少。而因為呢個OvershootInterpolator接納嘅係一個彈力(浮點)值,佢經過一定算法計算出個時間……如果要根據呢個彈力轉換做距離數值,就比較麻煩,所以我只系求其加咗1/10個半徑。想追求完美嘅~可以自行研究下OvershootInterpolator類同Animation類,http://www.oschina.net可以揾倒android
120                 // sdk嘅源碼。
121                 thislps.width = (int) (radius * 1.1 + mBottom.getWidth());
122             }
123         }
124         if (pCode == LEFTCENTER || pCode == RIGHTCENTER) {
125             if (thislps.height != -1
126                     && thislps.height != -2
127                     && thislps.height < (radius + mBottom.getHeight() + radius * 0.1) * 2) {
128                 thislps.width = (int) ((radius * 1.1 + mBottom.getHeight()) * 2);
129             }
130         } else {
131             if (thislps.height != -1
132                     && thislps.height != -2
133                     && thislps.height < radius + mBottom.getHeight() + radius
134                             * 0.1) {
135                 thislps.height = (int) (radius * 1.1 + mBottom.getHeight());
136             }
137         }
138         this.setLayoutParams(thislps);
139         // 兩個主要層
140         RelativeLayout rl1 = new RelativeLayout(mycontext);// 包含若干子按鈕嘅層
141 
142         rlButton = new RelativeLayout(mycontext); // 主按扭
143         llayouts = new LinearLayout[imgResId.length];
144         // N個子按鈕
145         for (int i = 0; i < imgResId.length; i++) {
146             ImageView img = new ImageView(mycontext);// 子按扭圖片
147 
148             img.setImageResource(imgResId[i]);
149             LinearLayout.LayoutParams llps = new LinearLayout.LayoutParams(
150                     LinearLayout.LayoutParams.WRAP_CONTENT,
151                     LinearLayout.LayoutParams.WRAP_CONTENT);
152 
153             img.setLayoutParams(llps);
154             llayouts[i] = new LinearLayout(mycontext);// 子按鈕層
155             llayouts[i].setId(100 + i);// 隨便設個id,方便onclick嘅時候識別返出嚟。呢個id值係求其設嘅,如果發現同其他控件沖突就自行改一下。
156             llayouts[i].addView(img);
157 
158             RelativeLayout.LayoutParams rlps = new RelativeLayout.LayoutParams(
159                     RelativeLayout.LayoutParams.WRAP_CONTENT,
160                     RelativeLayout.LayoutParams.WRAP_CONTENT);
161             rlps.alignWithParent = true;
162             rlps.addRule(align1, RelativeLayout.TRUE);
163             rlps.addRule(align2, RelativeLayout.TRUE);
164             llayouts[i].setLayoutParams(rlps);
165             llayouts[i].setVisibility(View.INVISIBLE);// 此处不能为GONE
166             rl1.addView(llayouts[i]);
167         }
168         RelativeLayout.LayoutParams rlps1 = new RelativeLayout.LayoutParams(
169                 RelativeLayout.LayoutParams.FILL_PARENT,
170                 RelativeLayout.LayoutParams.FILL_PARENT);
171         rlps1.alignWithParent = true;
172         rlps1.addRule(align1, RelativeLayout.TRUE);
173         rlps1.addRule(align2, RelativeLayout.TRUE);
174         rl1.setLayoutParams(rlps1);
175 
176         RelativeLayout.LayoutParams buttonlps = new RelativeLayout.LayoutParams(
177                 RelativeLayout.LayoutParams.WRAP_CONTENT,
178                 RelativeLayout.LayoutParams.WRAP_CONTENT);
179         buttonlps.alignWithParent = true;
180         buttonlps.addRule(align1, RelativeLayout.TRUE);
181         buttonlps.addRule(align2, RelativeLayout.TRUE);
182         rlButton.setLayoutParams(buttonlps);
183         rlButton.setBackgroundResource(showhideButtonId);
184         cross = new ImageView(mycontext);
185         cross.setImageResource(crossId);
186         RelativeLayout.LayoutParams crosslps = new RelativeLayout.LayoutParams(
187                 RelativeLayout.LayoutParams.WRAP_CONTENT,
188                 RelativeLayout.LayoutParams.WRAP_CONTENT);
189         crosslps.alignWithParent = true;
190         crosslps.addRule(CENTER_IN_PARENT, RelativeLayout.TRUE);
191         cross.setLayoutParams(crosslps);
192         rlButton.addView(cross);
193         myani = new myAnimations(rl1, pCode, radius);
194         rlButton.setOnClickListener(new OnClickListener() {
195             @Override
196             public void onClick(View v) {
197                 if (areButtonsShowing) {
198                     myani.startAnimationsOut(duretime);
199                     cross.startAnimation(myAnimations.getRotateAnimation(-270,
200                             0, duretime));
201                 } else {
202                     myani.startAnimationsIn(duretime);
203                     cross.startAnimation(myAnimations.getRotateAnimation(0,
204                             -270, duretime));
205                 }
206                 areButtonsShowing = !areButtonsShowing;
207             }
208         });
209 
210         cross.startAnimation(myAnimations.getRotateAnimation(0, 360, 200));
211         this.addView(rl1);
212         this.addView(rlButton);
213         hasInit = true;
214 
215     }
216 
217     /**
218      * 收埋
219      */
220     public void collapse() {
221         myani.startAnimationsOut(duretime);
222         cross.startAnimation(myAnimations.getRotateAnimation(-270, 0, duretime));
223         areButtonsShowing = false;
224     }
225 
226     /**
227      * 打開
228      */
229     public void expand() {
230         myani.startAnimationsIn(duretime);
231         cross.startAnimation(myAnimations.getRotateAnimation(0, -270, duretime));
232         areButtonsShowing = true;
233     }
234 
235     /**
236      * 初始化咗未(其實冇乜用,原來有就保留)
237      */
238     public boolean isInit() {
239         return hasInit;
240     }
241 
242     /**
243      * 有冇展開(其實冇乜用,原來有就保留)
244      */
245     public boolean isShow() {
246         return areButtonsShowing;
247     }
248 
249     /**
250      * 設置各子按鈕嘅onclick事件
251      */
252     public void setButtonsOnClickListener(final OnClickListener l) {
253 
254         if (llayouts != null) {
255             for (int i = 0; i < llayouts.length; i++) {
256                 if (llayouts[i] != null)
257                     llayouts[i].setOnClickListener(new OnClickListener() {
258 
259                         @Override
260                         public void onClick(final View view) {
261                             //此处添加其他事件比如按钮增大或者缩回菜单
262                             collapse();
263                             l.onClick(view);
264                         }
265 
266                     });
267             }
268         }
269     }
270 }
271  Desktop version

 

posted @ 2015-05-19 11:47  少於無  阅读(161)  评论(0)    收藏  举报