Android模組化編程——炫酷小巧多功能Button

來源:互聯網
上載者:User

標籤:

        前段時間客戶需求,要加幾個按鈕,包括清理緩衝,關於,設定,定位等。可是介面已經做好了,再重新布局介面,很麻煩。所以做了這麼個小Button。在此分享,供大家學習。下面是幾張,動畫效果沒工具儲存,是依次展開的。文末附有源碼下載連結。



首先上自訂布局檔案:ComposerLayout.java

package com.example.button;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.util.AttributeSet;import android.view.View;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.RelativeLayout;@SuppressLint("ViewConstructor")public class ComposerLayout extends RelativeLayout {public static byte RIGHTBOTTOM = 1, CENTERBOTTOM = 2, LEFTBOTTOM = 3,LEFTCENTER = 4, LEFTTOP = 5, CENTERTOP = 6, RIGHTTOP = 7,RIGHTCENTER = 8;private boolean hasInit = false; private boolean areButtonsShowing = false;private Context mycontext;private ImageView cross; private RelativeLayout rlButton;private Animations myani; private LinearLayout[] llayouts; private int duretime = 300;public ComposerLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);this.mycontext = context;}public ComposerLayout(Context context, AttributeSet attrs) {super(context, attrs);this.mycontext = context;}public ComposerLayout(Context context) {super(context);this.mycontext = context;}/** * 初始化 *  * @param imgResId *            子按鈕圖片drawable的id * @param showhideButtonId *            主按鈕drawable的id * @param crossId *            主按鈕上面十字片drawable的id * @param pCode *            位置代碼,例如“右上方”ALIGN_PARENT_BOTTOM|ALIGN_PARENT_RIGHT * @param radius *             * @param durationMillis *            動畫耗時 */public void init(int[] imgResId, int showhideButtonId, int crossId,byte pCode, int radius, final int durationMillis) {duretime = durationMillis;int align1 = 12, align2 = 14;if (pCode == RIGHTBOTTOM) { // 右下角align1 = ALIGN_PARENT_RIGHT;align2 = ALIGN_PARENT_BOTTOM;} else if (pCode == CENTERBOTTOM) {// 中下align1 = CENTER_HORIZONTAL;align2 = ALIGN_PARENT_BOTTOM;} else if (pCode == LEFTBOTTOM) { // 左下角align1 = ALIGN_PARENT_LEFT;align2 = ALIGN_PARENT_BOTTOM;} else if (pCode == LEFTCENTER) { // 左中align1 = ALIGN_PARENT_LEFT;align2 = CENTER_VERTICAL;} else if (pCode == LEFTTOP) { // 左上方align1 = ALIGN_PARENT_LEFT;align2 = ALIGN_PARENT_TOP;} else if (pCode == CENTERTOP) { // 中上align1 = CENTER_HORIZONTAL;align2 = ALIGN_PARENT_TOP;} else if (pCode == RIGHTTOP) { // 右上方align1 = ALIGN_PARENT_RIGHT;align2 = ALIGN_PARENT_TOP;} else if (pCode == RIGHTCENTER) { // 右中align1 = ALIGN_PARENT_RIGHT;align2 = CENTER_VERTICAL;}// 處理半徑RelativeLayout.LayoutParams thislps = (LayoutParams) this.getLayoutParams();Bitmap mBottom = BitmapFactory.decodeResource(mycontext.getResources(),imgResId[0]);if (pCode == CENTERBOTTOM || pCode == CENTERTOP) {if (thislps.width != -1&& thislps.width != -2&& thislps.width < (radius + mBottom.getWidth() + radius * 0.1) * 2) {thislps.width = (int) ((radius * 1.1 + mBottom.getWidth()) * 2);}} else {if (thislps.width != -1&& thislps.width != -2&& thislps.width < radius + mBottom.getWidth() + radius* 0.1) { thislps.width = (int) (radius * 1.1 + mBottom.getWidth());}}if (pCode == LEFTCENTER || pCode == RIGHTCENTER) {if (thislps.height != -1&& thislps.height != -2&& thislps.height < (radius + mBottom.getHeight() + radius * 0.1) * 2) {thislps.width = (int) ((radius * 1.1 + mBottom.getHeight()) * 2);}} else {if (thislps.height != -1&& thislps.height != -2&& thislps.height < radius + mBottom.getHeight() + radius* 0.1) {thislps.height = (int) (radius * 1.1 + mBottom.getHeight());}}this.setLayoutParams(thislps);RelativeLayout rl1 = new RelativeLayout(mycontext);// 包含若干子按鈕rlButton = new RelativeLayout(mycontext); // 主按扭llayouts = new LinearLayout[imgResId.length];// N個子按鈕for (int i = 0; i < imgResId.length; i++) {ImageView img = new ImageView(mycontext);// 子按扭圖片img.setImageResource(imgResId[i]);LinearLayout.LayoutParams llps = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);img.setLayoutParams(llps);llayouts[i] = new LinearLayout(mycontext);// 子按鈕llayouts[i].setId(100 + i);// 隨便設個id,方便onclick的時候識別。隨便設,如果發現同其他控制項沖突就自行改一下。llayouts[i].addView(img);RelativeLayout.LayoutParams rlps = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);rlps.alignWithParent = true;rlps.addRule(align1, RelativeLayout.TRUE);rlps.addRule(align2, RelativeLayout.TRUE);llayouts[i].setLayoutParams(rlps);llayouts[i].setVisibility(View.INVISIBLE);// 此處不能為GONErl1.addView(llayouts[i]);}RelativeLayout.LayoutParams rlps1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,RelativeLayout.LayoutParams.FILL_PARENT);rlps1.alignWithParent = true;rlps1.addRule(align1, RelativeLayout.TRUE);rlps1.addRule(align2, RelativeLayout.TRUE);rl1.setLayoutParams(rlps1);RelativeLayout.LayoutParams buttonlps = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);buttonlps.alignWithParent = true;buttonlps.addRule(align1, RelativeLayout.TRUE);buttonlps.addRule(align2, RelativeLayout.TRUE);rlButton.setLayoutParams(buttonlps);rlButton.setBackgroundResource(showhideButtonId);cross = new ImageView(mycontext);cross.setImageResource(crossId);RelativeLayout.LayoutParams crosslps = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);crosslps.alignWithParent = true;crosslps.addRule(CENTER_IN_PARENT, RelativeLayout.TRUE);cross.setLayoutParams(crosslps);rlButton.addView(cross);myani = new Animations(rl1, pCode, radius);rlButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if (areButtonsShowing) {myani.startAnimationsOut(duretime);cross.startAnimation(Animations.getRotateAnimation(-270,0, duretime));} else {myani.startAnimationsIn(duretime);cross.startAnimation(Animations.getRotateAnimation(0,-270, duretime));}areButtonsShowing = !areButtonsShowing;}});cross.startAnimation(Animations.getRotateAnimation(0, 360, 200));this.addView(rl1);this.addView(rlButton);hasInit = true;}public void collapse() {myani.startAnimationsOut(duretime);cross.startAnimation(Animations.getRotateAnimation(-270, 0, duretime));areButtonsShowing = false;}public void expand() {myani.startAnimationsIn(duretime);cross.startAnimation(Animations.getRotateAnimation(0, -270, duretime));areButtonsShowing = true;}public boolean isInit() {return hasInit;}public boolean isShow() {return areButtonsShowing;}/** * 設定各子按鈕OnClick事件 */public void setButtonsOnClickListener(final OnClickListener l) {if (llayouts != null) {for (int i = 0; i < llayouts.length; i++) {if (llayouts[i] != null)llayouts[i].setOnClickListener(new OnClickListener() {@Overridepublic void onClick(final View view) {//此處添加其他事件比如按鈕增大或者縮回菜單collapse();l.onClick(view);}});}}}}
這裡自訂了一個BaseActivity,使用BaseActivity的好處不用我說了吧:

package com.example.button;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;public abstract class BaseActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setView();initView();setListener();initData();}@Overrideprotected void onResume() {super.onResume();}@Overrideprotected void onPause() {super.onPause();}/** * 設定布局檔案 */public abstract void setView();/** * 初始化布局檔案中的控制項 */public abstract void initView();/** * 設定控制項的監聽 */public abstract void setListener();private void initData() {String appID = "wx88818f8c48a95eb4";}@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);}}
動畫設定類,Animations,這裡用了一個開源動畫庫nineoldandroids.jar。下載文末原代碼中有

package com.example.button;import static com.nineoldandroids.view.ViewPropertyAnimator.animate;import java.util.ArrayList;import java.util.List;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.LinearLayout;import com.nineoldandroids.animation.Animator;import com.nineoldandroids.animation.Animator.AnimatorListener;import com.nineoldandroids.view.ViewPropertyAnimator;public class Animations {public final int R; // 半徑public static byte RIGHTBOTTOM = 1, CENTERBOTTOM = 2, LEFTBOTTOM = 3,LEFTCENTER = 4, LEFTTOP = 5, CENTERTOP = 6, RIGHTTOP = 7,RIGHTCENTER = 8;private int pc; // 位置代號private ViewGroup clayout; // 父layoutprivate final int amount; // 有幾多個按鈕private double fullangle = 180.0;// 在幾大嘅角度內排佈private byte xOri = 1, yOri = 1; // x、y值嘅方向,即系向上還是向下private boolean isOpen = false;// 記錄是已經開啟還是關閉private List<ViewPropertyAnimator> viewAnimators = new ArrayList<ViewPropertyAnimator>();/** * 構造函數 *  * @param comlayout *            包裹彈出按鈕嘅layout * @param poscode *            位置代號,分別對應RIGHTBOTTOM、CENTERBOTTOM、LEFTBOTTOM、LEFTCENTER、 *            LEFTTOP、CENTERTOP、RIGHTTOP、RIGHTCENTER * @param radius *            半徑 */public Animations(ViewGroup comlayout, int poscode, int radius) {this.pc = poscode;this.clayout = comlayout;this.amount = clayout.getChildCount();this.R = radius;// 初始化動畫,每個view對應一個animatorfor (int i = 0; i < amount; i++) {View childAt = clayout.getChildAt(i);ViewPropertyAnimator anim = animate(childAt);viewAnimators.add(anim);}if (poscode == RIGHTBOTTOM) { // 右下角fullangle = 90;xOri = -1;yOri = -1;} else if (poscode == CENTERBOTTOM) {// 中下fullangle = 180;xOri = -1;yOri = -1;} else if (poscode == LEFTBOTTOM) { // 左下角fullangle = 90;xOri = 1;yOri = -1;} else if (poscode == LEFTCENTER) { // 左中fullangle = 180;xOri = 1;yOri = -1;} else if (poscode == LEFTTOP) { // 左上方fullangle = 90;xOri = 1;yOri = 1;} else if (poscode == CENTERTOP) { // 中上fullangle = 180;xOri = -1;yOri = 1;} else if (poscode == RIGHTTOP) { // 右上方fullangle = 90;xOri = -1;yOri = 1;} else if (poscode == RIGHTCENTER) { // 右中fullangle = 180;xOri = -1;yOri = -1;}}private class AnimListener implements AnimatorListener {private View target;public AnimListener(View _target) {target = _target;}@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {if (!isOpen) {target.setVisibility(View.INVISIBLE);}}@Overridepublic void onAnimationCancel(Animator animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator animation) {// TODO Auto-generated method stub}}<pre name="code" class="java">        /** * 開 */
public void startAnimationsIn(int durationMillis) {isOpen = true;for (int i = 0; i < clayout.getChildCount(); i++) {final LinearLayout inoutimagebutton = (LinearLayout) clayout.getChildAt(i);double offangle = fullangle / (amount - 1);final double deltaY, deltaX;if (pc == LEFTCENTER || pc == RIGHTCENTER) {deltaX = Math.sin(offangle * i * Math.PI / 180) * R;deltaY = Math.cos(offangle * i * Math.PI / 180) * R;} else {deltaY = Math.sin(offangle * i * Math.PI / 180) * R;deltaX = Math.cos(offangle * i * Math.PI / 180) * R;}ViewPropertyAnimator viewPropertyAnimator = viewAnimators.get(i);viewPropertyAnimator.setListener(null);inoutimagebutton.setVisibility(View.VISIBLE);viewPropertyAnimator.x((float) (inoutimagebutton.getLeft() + xOri * deltaX)).y((float) (inoutimagebutton.getTop() + yOri * deltaY));}}/** * 收 */public void startAnimationsOut(int durationMillis) {isOpen = false;for (int i = 0; i < clayout.getChildCount(); i++) {final LinearLayout inoutimagebutton = (LinearLayout) clayout.getChildAt(i);ViewPropertyAnimator viewPropertyAnimator = viewAnimators.get(i);viewPropertyAnimator.setListener(null);viewPropertyAnimator.x((float) inoutimagebutton.getLeft()).y((float) inoutimagebutton.getTop());viewPropertyAnimator.setListener(new AnimListener(inoutimagebutton));}}public int getPosCode() {return this.pc;}/** * 自轉函數 * * @param fromDegrees * 從多少度 * @param toDegrees * 到多少度 * @param durationMillis * m */public static Animation getRotateAnimation(float fromDegrees,float toDegrees, int durationMillis) {RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);rotate.setDuration(durationMillis);rotate.setFillAfter(true);return rotate;}}
主Activity:TestActivity

package com.example.button;import android.view.View;import android.view.View.OnClickListener;import android.widget.RelativeLayout;import android.widget.Toast;public class TestActivity extends BaseActivity {private ComposerLayout clayout;@Overridepublic void setView() {setContentView(R.layout.activity_main);}@Overridepublic void initView() {// 引用控制項clayout = (ComposerLayout) findViewById(R.id.test);clayout.init(new int[] { R.drawable.composer_camera,R.drawable.composer_music, R.drawable.composer_place,R.drawable.composer_sleep, R.drawable.composer_thought,R.drawable.composer_with }, R.drawable.composer_button,R.drawable.composer_icn_plus, ComposerLayout.RIGHTCENTER, 180,300);}@Overridepublic void setListener() {// 點擊事件監聽,100+0對應composer_camera,100+1對應composer_music……如此類推你有機個按鈕就加幾個按鈕都行。OnClickListener clickit = new OnClickListener() {@Overridepublic void onClick(View v) {if (v.getId() == 100 + 0) {Toast.makeText(TestActivity.this, "測試A", 0).show();} else if (v.getId() == 100 + 1) {Toast.makeText(TestActivity.this, "測試B...", 0).show();} else if (v.getId() == 100 + 2) {Toast.makeText(TestActivity.this, "測試C...", 0).show();} else if (v.getId() == 100 + 3) {Toast.makeText(TestActivity.this, "測試D...", 0).show();} else if (v.getId() == 100 + 4) {Toast.makeText(TestActivity.this, "測試E...", 0).show();} else if (v.getId() == 100 + 5) {Toast.makeText(TestActivity.this, "測試F..", 0).show();}}};clayout.setButtonsOnClickListener(clickit);RelativeLayout rl = (RelativeLayout) findViewById(R.id.rlparent);rl.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubToast.makeText(TestActivity.this, "父控制項可以點擊的哦!!!", 0).show();System.out.println("父控制項可以點擊。");}});}}

接下來是布局檔案activity_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/rlparent"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="#ABCDEF" >    <com.example.button.ComposerLayout        android:id="@+id/test"        android:layout_width="20dp"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_centerVertical="true" >    </com.example.button.ComposerLayout></RelativeLayout>


下載nineoldandroids-2.4.0.jar

下載Demo



Android模組化編程——炫酷小巧多功能Button

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.