微信底部導航漸層效果-----viewpager&PorterDuffXfermode,漸層-----viewpager

來源:互聯網
上載者:User

底部導航漸層效果-----viewpager&PorterDuffXfermode,漸層-----viewpager

實現這個功能主要涉及的知識點有

ViewPager關於ViewPager需要注意的知識主要是OnPageChangeListener,該介面的三個方法如下
public abstract void onPageScrollStateChanged (int state)public abstract void onPageScrolled (int position, float positionOffset, int positionOffsetPixels)public abstract void onPageSelected (int position)

第一個方法onPageScrollStateChanged 中的參數state,有三個可取的值
public static final int SCROLL_STATE_DRAGGINGConstant Value: 1 (0x00000001)public static final int SCROLL_STATE_IDLEConstant Value: 0 (0x00000000)public static final int SCROLL_STATE_SETTLINGConstant Value: 2 (0x00000002)

SCROLL_STATE_DRAGGING:手指按在viewpager上滑動時
SCROLL_STATE_SETTLING:手指鬆開後,viewpager自動滑動期間
SCROLL_STATE_IDLE:viewpager滑動進入了某個page。
如果你在onPageScrollStateChanged 中輸出state的值,你會發現每次都是按順序列印出“1---2----0”

第二個方法onPageScrolled的三個參數position:滑動時,螢幕左側顯示的第一個page
positionOffset:滑動比例,值的範圍為[0, 1),手指往左滑動,該值遞增,反之遞減
positionOffsetPixels:滑動距離,和螢幕有關,手指往左滑動,該值遞增,反之遞減

我們經常需要檢查viewpager的滑動方向並作出一些操作,這時你只需要通過position和positionOffset兩個值即可實現該功能。

第三個方法onPageSelected的三個參數position:當前選擇的page序號
該方法被調用的時間比較特別,在上面的第一個方法中的“1---2----0”中的2執行之後,onPageSelected就執行,然後執行“1---2----0”中的0。就是手指鬆開螢幕之後,onPageSelected被執行。
以下在代碼中自己重寫的一個OnPageChangeListener
/** * @author Quinn * @date 2015-2-28 */public class MainPagerChangeListener implements OnPageChangeListener{public interface PagerCallback{public void changePageColor(int index, int offset);}private PagerCallback callback;public MainPagerChangeListener(MainActivity mainActivity){this.callback  = (PagerCallback)mainActivity;}//順序為1-2-0@Overridepublic void onPageScrollStateChanged(int state) {}@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {if(positionOffset != 0.0f){callback.changePageColor(position+1,  (int)(positionOffset * 255));callback.changePageColor(position,  (int)((1-positionOffset) * 255));}}@Overridepublic void onPageSelected(int position) {}}

首先我們留一個回調介面PagerCallback,然後在onPageScrolled中執行操作。可以根據position和positionOffset兩個值,對兩個方向的page進行不同的操作。我們這裡進行的操作是改變表徵圖的顏色。
PorterDuffXfermode先看以下這幅圖


的底部圖案,其原型是一個灰色的圖案,在滑動時,會發生色彩坡形,那麼怎樣使一張圖片產生這樣的效果呢?其原理是利用PorterDuffXfermode!先看以下這張圖片

上述16個圖,我們看第二排的第三個,黃色部分代表Dst,藍色部分代表Src,將Dst覆蓋在Src之上,選擇"DstIn"模式,就可以合成上述第二排第三張圖片。那麼,如果Src是一個灰色的圖片(圖片部分是透明的,像上面的四個表徵圖),Dst是一個綠色的矩形,其大小和圖片一致。然後將綠色的矩形覆蓋在圖片之上,選擇“DstIn”模式,就能達到將圖片設定成綠色的效果。在這個基礎上,要對圖片進行色彩坡形,只需在viewpager滑動時修改上述Dst矩形的顏色透明度即可。實現代碼可以在文章末尾下載源碼。部落客要記錄實現思路和細節,貼出代碼感覺太冗長了。自訂視圖自訂視圖,一般按以下步驟進行
  • 自訂屬性
  • 擷取屬性
  • 重寫onMeasure
  • 重寫onDraw
我們在自訂底部帶文字的表徵圖,自訂屬性如下:
路徑:XMPP\res\values\attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="FooterTextIcon">        <attr name="iconSrc" format="reference" />        <attr name="color" format="color"/>        <attr name="text" format="string"/>        <attr name="textSize" format="dimension"/>    </declare-styleable></resources>

這些自訂屬性的使用方式如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:FooterIcon="http://schemas.android.com/apk/res/com.quinn.xmpp"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.quinn.xmpp.ui.main.MainActivity" >//省略,,,,//,,,//,,, <com.quinn.xmpp.ui.widget.FooterTextIcon            android:id="@+id/chattingIcon"            android:layout_width="0dip"            android:layout_height="match_parent"            android:layout_weight="1"            FooterIcon:iconSrc="@drawable/ic_action_chat"            FooterIcon:text="聊天"            FooterIcon:textSize="12sp"            android:padding="5dip"            FooterIcon:color="#ff181818" />//省略,,,,//,,,//,,,</LinearLayout>

在使用自訂屬性時,需要在使用這些自訂屬性的布局檔案中引入一個命名空間,比如上述代碼的第三行,它的格式是:
xmlns:自己起一個名字="http://schemas.android.com/apk/res/應用的包名"
注意,上面代碼的最後一部分是應用的包名,而不是某個Activity的包名或者自訂群組件對應Java檔案的包名
前面自訂屬性的attrs.xml中,可以自訂的屬性類型(對應上述的format)有以下幾種reference、string、color、dimension、boolean、integer、float、fraction、enum、flag主要講講其中比較常用而且容易混淆的四個reference的值必須是"@drawable/xxxxxx"比如上面的
FooterIcon:iconSrc="@drawable/ic_action_chat"
而string,color,dimension的值可以直接寫某個值,也可以是引用於資源檔string.xml,color.xml,dimens.xml比如
            FooterIcon:text="聊天"            FooterIcon:textSize="12sp"            android:padding="5dip"            FooterIcon:color="#ff181818"</span>
也可以寫成
            FooterIcon:text="@string/xxxxx"            FooterIcon:textSize="@dimen/xxxx"            android:padding="@dimen/xxxx"            FooterIcon:color="@color/xxxx" />
然後,我們需要在一個地方使用這些屬性的值,就是在我們的自訂群組件的類檔案中。如下:
public class FooterTextIcon extends View {//四個屬性private String text;private int themeColor;private int textSize;private int iconRid;//、、、/** * @param context */public FooterTextIcon(Context context) {this(context, null);}public FooterTextIcon(Context context, AttributeSet attrs) {this(context, attrs, 0);}/** * @param context * @param attrs * @param defStyleAttr */public FooterTextIcon(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.FooterTextIcon);iconRid = a.getResourceId(R.styleable.FooterTextIcon_iconSrc, -1);text = a.getString(R.styleable.FooterTextIcon_text);textSize = (int) a.getDimension(R.styleable.FooterTextIcon_textSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12,getResources().getDisplayMetrics()));themeColor = a.getColor(R.styleable.FooterTextIcon_color, Color.parseColor(DEFAULT_CHOSEN_COLOR));a.recycle();                //,,,}        //,,省略,,}
如上,我們在建構函式中,通過一個TypeArray對象擷取各種類型的屬性,並且最後調用TypeArray的recycle函數回收記憶體。一般我們將這些代碼放在有三個參數的構造方法中執行,而又一個參數的構造方法直接用this指標調用有兩個參數的構造方法,同理,兩個的調用三個的。

關於自訂群組件的知識可以參考另外兩篇部落格android自訂View-------滑動按鈕
android自訂View-------為什麼重寫onMeasure()以及怎麼重寫


該功能目前應用於我的XMPP項目  https://github.com/Leaking/xmppIM
後續堅持把寫這個開源項目使用到的知識都記錄在部落格裡。





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.