1. 程式人生 > >Android開發技巧——實現可複用的ActionSheet選單

Android開發技巧——實現可複用的ActionSheet選單

本文原創,轉載請註明出處:

對於要實現的可複用的控制元件庫,我需要它具備以下兩點:

  1. 可新增遠端依賴(不考慮Eclipse中的使用)
  2. 可靈活配置

分離庫的實現程式碼

對於第一點,需要做的就是在Android Studio中新建一個library的module,然後把相關的實現程式碼,資源分離出來拖過去,並且把library中如圖示,一些字串等沒有用到的資源刪掉,保持AndroidManifest.xml的乾淨(僅保留會用到的許可權,宣告等)。在這裡,我們library的AndroidManifest最終只剩下了:

<manifest
    package="com.githang.android.actionsheet"
>
<application/> </manifest>

注意,application節點裡 的allowBackup屬性要去掉,不然會讓一些不知道怎麼用tools中的幾個屬性來解決衝突的人,面對AndroidManifest.xml的合併衝突不知所措。labelicon屬性在這裡也不需要,所以也去掉了。

然後把一開始建立的app module的包名加上.demo字尾,把com.githang.andorid.actionsheet僅作為我們的library的包名(這個是純屬個人習慣,你也可以不這麼做。我是覺得在包名上把library和demo區分來比較好,而我又不想給library加多一個.library

的包。

分離之後,就可以把我們的庫打包成aar,並上傳到jcenter,讓別人能以新增遠端依賴的方式來使用了。如何釋出到jcenter,可以見我這篇部落格:《使用Gradle釋出Android開源專案到JCenter》

但是現在,我們僅完成的最基本的工作,因為,你不能要求每個人對一個庫的要求都和你完全一樣,可能有些人的需求中,需要改一下UI上的一些屬性什麼的。所以接下來,我們需要讓我們的庫能夠靈活配置。

可自由配置的屬性

我們的大部分屬性是定義在xml中的。要改動這些屬性,方法主要有兩種:
1. 在Java程式碼中提供一些View的UI上的介面,讓第三方通過呼叫它來設定。
2. 佈局檔案中使用屬性的引用,而不是直接使用它的值。

如果你寫的是自定義控制元件(通過繼承View),那麼你可能還需要自定義一些屬性,讓別人在使用的時候可以在xml中新增。由於這裡我們寫的不是這類控制元件,不需要用到它,在這裡就不贅述了。

繼續說上面的兩種方法。Android中,採用xml定義佈局,就是想讓佈局程式碼與邏輯程式碼相分離,所以第一種方式我是儘量少用的(在需要動態設定,或者是在Java程式碼中設定更簡單時使用,)。下面先說一下第二種的方式的實現過程。

我們在xml中定義到的控制元件有三個,一是ListView,二是Button,三是ListView的Item。所以首先,在values資料夾裡新建一個attrs.xml的屬性檔案,在裡面分別定義三個屬性,formatreference。如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="ActionSheetList" format="reference"/>
    <attr name="ActionSheetCancel" format="reference"/>
    <attr name="ActionSheetItem" format="reference"/>
</resources>

接著,把之前寫的佈局檔案改為使用?attr的方式宣告屬性。

menu_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@android:id/text1"
          style="?attr/ActionSheetItem" />

dialog_action_sheet.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <ListView
        android:id="@+id/menu_items"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?attr/ActionSheetList"
        android:listSelector="@android:color/transparent"/>

    <Button
        android:id="@+id/menu_cancel"
        style="?attr/ActionSheetCancel"/>
</LinearLayout>

然後在我們的style中宣告這幾個屬性的style:

    <style name="ActionSheetList">
        <item name="android:divider">#c9dddddd</item>
        <item name="android:dividerHeight">1px</item>
    </style>
    <style name="ActionSheetItem">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">45dp</item>
        <item name="android:textSize">18sp</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">@color/menu_text</item>
    </style>
    <style name="ActionSheetCancel" parent="ActionSheetItem">
        <item name="android:layout_marginTop">8dp</item>
        <item name="android:layout_marginBottom">8dp</item>
        <item name="android:background">@drawable/menu_item_single</item>
    </style>

注意,這裡的style的名稱並不要求與attr中宣告的名稱一致,這裡我只是懶得想其他名字,真的。

這樣做了之後,其他人在使用的時候,會需要多一個步驟:在他的styler中的AppTheme(具體視androidmanifest中指定的theme而定)節點中,需要新增以下幾項:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="ActionSheetList">@style/ActionSheetList</item>
        <item name="ActionSheetItem">@style/ActionSheetItem</item>
        <item name="ActionSheetCancel">@style/ActionSheetCancel</item>
    </style>

如果他想自己修改屬性的值,只需要寫對應的style,然後把上面的item裡的值改為他寫的style即可。

對於選單的改動,我們就改到這裡。
接下來是對ActionSheetDialog的重構,讓它提供可以進行以下設定的API:

  • 設定顯示與隱藏時的動畫
  • 設定選單的背景

首先是選單的背景,上文已經說過它一共有四個背景。所以定義一個選單背景的類:

    /**
     * 選單背景
     */
    public static class MenuBackground {
        public int top;
        public int middle;
        public int bottom;
        public int single;

        public MenuBackground() {}

        public MenuBackground(int top, int middle, int bottom, int single) {
            this.top = top;
            this.middle = middle;
            this.bottom = bottom;
            this.single = single;
        }
    }

然後定義一個選單背景的物件,給它初始值,並定義一個設定背景的方法:

    private MenuBackground mMenuBg = new MenuBackground(R.drawable.menu_item_top,
            R.drawable.menu_item_middle, R.drawable.menu_item_bottom, R.drawable.menu_item_single);

    public void setMenuBackground(int top, int middle, int bottom, int single) {
        mMenuBg.top = top;
        mMenuBg.middle = middle;
        mMenuBg.bottom = bottom;
        mMenuBg.single = single;
    }

最後剩下動畫的配置的。定義分別設定顯示及隱藏動畫的兩個方法,注意,對隱藏動畫的方法中,要設定動畫結束的回撥,在這裡隱藏我們的選單。

動畫設定的程式碼重構如下:

    private void initAnim(Context context) {
        setShowAnimation(AnimationUtils.loadAnimation(context, R.anim.translate_up));
        setDismissAnimation(AnimationUtils.loadAnimation(context, R.anim.translate_down));
    }

    /**
     * @param animation Showing animation.
     * @since 0.2
     */
    public void setShowAnimation(Animation animation) {
        mShowAnim = animation;
    }

    /**
     * @param animation Dismissing animation.
     * @since 0.2
     */
    public void setDismissAnimation(Animation animation) {
        mDismissAnim = animation;
        mDismissAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                dismissMe();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

現在我們的庫已經重構完了,它暴露了適當的API,以讓其他人可以自定義一些屬性。它也對佈局檔案的配置提供了方法,即通過style來進行配置。

最後就是升版本號,改README,釋出新版本了,打TAG了。

相關推薦

Android開發技巧——實現ActionSheet選單

本文原創,轉載請註明出處: 對於要實現的可複用的控制元件庫,我需要它具備以下兩點: 可新增遠端依賴(不考慮Eclipse中的使用) 可靈活配置 分離庫的實現程式碼 對於第一點,需要做的就是在Android Studio中新建一個libra

PHP學習——29 PHP面向物件(trait特性的宣告與使用技巧:實現程式碼的類方法集合)

自 PHP 5.4.0 起,PHP 實現了一種程式碼複用的方法,稱為 trait。 Trait 是為類似 PHP 的單繼承語言而準備的一種程式碼複用機制。Trait 為了減少單繼承語言的限制,使開發人員能夠自由地在不同層次結構內獨立的類中複用 method。Trait 和 Class 組合的

Android開發技巧——使用Dialog實現仿QQ的ActionSheet選單

最近看到有人用Dialog來實現QQ的仿ActionSheet的自定義選單,對於自己沒實現過的一些控制元件,看著也想實現一下。於是動手了一下,發現也不難,和大家分享一下。 在這裡我也是用Dialog來實現,程式碼不多,這裡說一下實現的過程。 選單的佈

搭建區域網Maven私服並結合Android Studio實現程式碼

每一種技術,每一個框架都不是憑空產生,都是為了解決特定需求.因此使用什麼技術取決於我們的需求,作為一個研發人員,我們不僅僅要懂得編碼,更要有洞察真實需求的能力. 首先介紹一下我們公司的現狀:我們公司有很多APP,每年會優化或者開發5個以上的APP,而

C#實現Socket接收/傳送共享緩衝區類

在Socket的接收/傳送方法:Send()、BeginSend()、Receive()、BeginReceive()中,第一個引數是位元組數陣列,表示當前接收資料區或需要傳送的資料。普通Socket應用中,往往是接收/傳送時建立陣列,使用後陣列空間由託管堆回收(Soc

Android開發技巧——五分鐘實現二維碼識別

/** * This activity opens the camera and does the actual scanning on a background * thread. It draws a viewfinder to help the user place the barcode cor

abp加DDD開發:低耦合、擴充套件的【工單】業務模組-簡介和整合

前言 很多場景【單體+模組化】比微服務更合適,開發難度低、程式碼可複用性強、可擴充套件性強。模組化開發有些難點,模組啟動與解除安裝、模組之間的依賴和通訊。asp.net core abp為我們提供了模組化開發能力及其它基礎功能。基於abp(一代6.3)結合DDD已基本開發好一個【工單管理模組】,本

Android開發技巧之:QQ第三方登入(二)

接 android QQ第三方登入(一)  獲取登入使用者名稱資訊,這邊先抱怨一下,官方API有點坑 Constants原始碼類下就是找不到GRAPH_SIMPLE_USER_INFO這個屬性!無語! 根據官方提供返回的的JSONObject資訊解析:

Android開發技巧之:QQ第三方登入(一)

使用的是Android_SDK_V2.9.1,建議使用最新版; 官方下載:SDK下載  Android studio 中新增到 然後在點選build.gradle檔案新增 配置AndroidManifest 在應用的Andr

做一個的 echarts-vue 元件(延遲動畫載入)

在 vue 專案使用 echarts 的場景中,以下三點不容忽視:1. 視覺化的資料往往是非同步載入的;2. 若一個頁面存在大量的圖表( 尤其當存在關係圖和地圖時 ),往往會導致該頁面的渲染速度很慢並可能在幾秒內卡死,產生極差的使用者體驗。3. 引入 echarts 元件導致編譯後的檔案過大從而使得首次訪

Android開發技巧不同狀態的Button

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

在vue中封裝的元件

本次封裝的元件以toast元件為例 以前使用移動端ui外掛時,通過一句程式碼比如 $.toast( ‘ 需要顯示的內容 ’ ),從而在頁面上展示這段文字,並在一定時間後消失。 現在我們也嘗試自己封裝toast元件。 準備工作:vue-cli腳手架工程 先看一下涉及到的檔案目錄截圖:

Android開發技巧(一):程式碼日誌跟蹤後臺顯示Log.i();

1.Activity中使用Log.i(); private static final String TAG = “GoodsSourceActivity”;//定義常量標記 Log.i(TAG,”—–TEST-BUNDLE——-“+uuid);//日誌列印,i級別 2.Fragme

Android開發實現多次點選事件

 使用Google提供的api中採用的演算法 能夠實現n次點選事件,我們需要定義一個n長度的陣列,每點選一次將數組裡的內容按序號整體向左移動一格,然後給n-1出即陣列的最後添加當前的時間,如果0個位置的時間大於當前時間減去1000毫秒的話,那麼證明在1000毫秒內點選了n次。實現如

Vue性&組合

  二、自定義指令 除了核心功能預設內建的指令(v-model和v-show),Vue也允許註冊自定義指令。在Vue2.0中,程式碼複用和抽象的主要形式是元件,然而有的情況下,你仍然需要對普通DOM元素進行底層操作,這時會用到自定義指令。如當頁面載入時,輸入框將獲得焦點,只要你

封裝高的服務端響應物件 --ServerResponse、ResponseCode

在平時的編碼過程中,返回給前端的資料都會統一規範起來,用一個泛型來作為響應物件 ServerResponse類 @JsonSerialize(include =  JsonSerialize.Inclusion.NON_NULL)//保證序列化json的時候,如果是nul

Android開發-listview實現多條目展示

如果我們的listview做的很好了 那麼多條目對你來說就很簡單了,因為多條目是基於listview的 它們只是在介面卡中有所不同 現在我們來看一下介面卡 public class MyAdapter extends BaseAdapter { private ArrayList&

分析模式:的物件模型中文版 pdf下載

第1章 緒論 1.1 概念模型 1.2 模式世界 1.2.1 Christopher Alexander 1.2.2 描述格式 1.2.3 關於模式的抽象程度 1.3 本書中的模式 1.3.1 建模例項 1.3.2 模式的來源 1.3.3 跨領域的模式 1.4 概念模型與

Vue性&組合

二、自定義指令 除了核心功能預設內建的指令(v-model和v-show),Vue也允許註冊自定義指令。在Vue2.0中,程式碼複用和抽象的主要形式是元件,然而有的情況下,你仍然需要對普通DOM元素進行底層操作,這時會用到自定義指令。如當頁面載入時,輸入框將獲得焦點,只

Android開發技巧——定製仿微信圖片裁剪控制元件

拍照——裁剪,或者是選擇圖片——裁剪,是我們設定頭像或上傳圖片時經常需要的一組操作。上篇講了Camera的使用,這篇講一下我對圖片裁剪的實現。 背景 下面的需求都來自產品。 裁剪圖片要像微信那樣,拖動和放大的是圖片,裁剪框不動。 裁剪框外的內容要有半透