在代碼中實現android:tint效果

2016-11-30遇到的一點小問題

Android著色效果tint

Android有個tint的著色效果,這樣有些純色圖片,如果需要顯示別的顏色效果,直接加上就行,特別方便。這個網上一搜就有,效果如圖:

android:tint="@color/x"

我這個原本是個黑色的圖標,加上這句,就可以顯示各種顏色。
使用很簡單,直接在XML加上android:tint="@color/colorPrimary"就行;如果是背景,加上android:backgroundTint="@color/colorPrimary"就行,比單純設置方便多了。
比如Button如果設置android:background="@color/colorPrimary"為純顏色,那樣會沒有點擊效果,需要點擊效果還需要寫個selector效果的drawable。如果要在Android5.0之上顯示漣漪效果,還需要在drawable-v21中創建一個同名字的ripple效果的drawable
XML寫法簡單,在代碼中卻有點麻煩。
網上搜索出來的方法有兩種:
第一種不去區分版本,使用V4包的android.support.v4.graphics.drawable.DrawableCompat

ImageView image = new ImageView(context);
Drawable up = ContextCompat.getDrawable(context,R.drawable.ic_sort_up);
Drawable drawableUp= DrawableCompat.wrap(up);
DrawableCompat.setTint(drawableUp, ContextCompat.getColor(context,R.color.theme));
image.setImageDrawable(drawableUp);

第二種只能在API21以上使用

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {    
    ImageView image = new ImageView(context);
    image.setImageResource(R.drawable.ic_sort_down);
    image.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(context,R.color.theme)));
}

第一種雖然好用,且向下兼容,但有個問題,就是如果我在A界面使用,先打開A界面,再去打開有使用同一個圖片的B界面,會發現即使B界面的該ImageView沒使用Tint,也會有對應的著色效果。除非先進入的B界面,或者退出應用。

看有個DrawableCompat.unwrap(...)方法,試了一下,不管用,stackoverflow找到答案
http://stackoverflow.com/questions/30945490/drawablecompat-unwrap-is-not-working-pre-lollipop
試了一下,可以了,完整如下:

ImageView image = new ImageView(context);

Drawable up = ContextCompat.getDrawable(context,R.drawable.ic_sort_up);
Drawable drawableUp= DrawableCompat.wrap(up);
DrawableCompat.setTint(drawableUp, ContextCompat.getColor(context,R.color.theme));

image.setImageDrawable(drawableUp);

layoutParams.addRule(RelativeLayout.RIGHT_OF, text.getId());
addView(image, layoutParams);

Drawable up1 = ContextCompat.getDrawable(context,R.drawable.ic_sort_up);
Drawable drawableUp1= DrawableCompat.unwrap(up1);
DrawableCompat.setTintList(drawableUp1, null);

倒數第三行寫的那樣,需要重新弄個*Drawable 出來,用的同一個會導致之前設置的著色無效;倒數第二行測試使用wrap();也沒出問題;最后一行一定用后面的那個Drawable *,用原來那個也會導致之前設置的著色無效。即使他們放在addView()之后。
當然,最后三行完整放在image.setImageDrawable(drawable);前面也是沒有問題的,這邊只是為了方便說明。
這些只是個人隨便寫的,又剛好有效,寫法不一定對。

點擊效果drawable

普通點擊效果 寫在drawable文件

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >    
      <item android:state_pressed="true">    
            <shape android:shape="rectangle">        
                  <solid android:color="#33000000"/>   
             </shape>
      </item>
      <item>    
            <shape android:shape="rectangle">        
                  <solid android:color="#FFFFFF"/>    
           </shape>
      </item>
</selector>

漣漪點擊效果 寫在drawable-v21文件

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="#33FFFFFF">    
    <item>        
        <shape android:shape="rectangle">            
            <solid android:color="#FFFFFF" />       
       </shape>    
    </item>
</ripple>
RelativeLayout相對位置設置

在XML中,RelativeLayout相對位置使用android:layout_toRightOf="@+id/view0"來設置;代碼中:

ImageView image = new ImageView(context);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.RIGHT_OF, text.getId());
rl.addView(image, lp);

需要注意,相對的控件如果是new出來的TextView text = new TextView(context);,需要調用setId()設置ID,text.setId(Integer.MAX_VALUE - 1000);,否則不生效。
2016-12-02發現了點問題
之前圖片相對在文字右邊,高度差不多,沒看出問題,今天換了個長圖片就發現高度不是居中了。
調了一下,貼一下正確代碼

<RelativeLayout    
    android:layout_width="match_parent"    
    android:layout_height="90dp">    
    <TextView        
        android:id="@+id/ddd"        
        android:layout_width="wrap_content"        
        android:layout_height="wrap_content"        
        android:layout_centerInParent="true"        
        android:paddingRight="5dp"        
        android:text="測試"/>    
    <TextView        
        android:layout_width="wrap_content"        
        android:layout_height="wrap_content"        
        android:layout_toRightOf="@+id/ddd"        
        android:layout_centerInParent="true"        
        android:text="你\n好\n啊"/>
</RelativeLayout>
TextView text = new TextView(context);
text.setId(Integer.MAX_VALUE - 1000);
text.setTextSize(16);
text.setText("文字");
text.setPadding(0,0,3,0);
text.setTextColor(ContextCompat.getColorStateList(context,R.color.a));
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
addView(text, params);

ImageView imageView = new ImageView(context);
imageView.setImageDrawable(isUp ? drawableUp :drawableDown);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
lp.addRule(RelativeLayout.RIGHT_OF , text.getId());
addView(imageView, lp);

因為是居中,所以不管是在XML還是在代碼中,第一個控件一定要寫android:layout_centerInParent這個屬性,第二個可以android:layout_centerVertical="true"android:layout_centerInParent="true",也要寫上,否則無效。代碼中第二個的addRule()方法,兩個記得要分開寫,剛開始寫一塊lp.addRule(RelativeLayout.CENTER_IN_PARENT|RelativeLayout.RIGHT_OF , text.getId());顯示出來很奇怪。效果如圖:

RelativeLayout.RIGHT_OF
簡書Markdown文本編輯模式

之前一直用的51CTO,不過那邊用著感覺太重了,看著累,而且搜索不方便,自己記的東西比較難找到。看簡書流行就換過來了。簡書有兩種文本編輯模式 富文本 和 Markdown,剛寫簡書不太懂,一直弄不成別人那種代碼樣式。昨天在幫助那邊找了找,看到了 http://www.lxweimin.com/p/q81RER 趕緊把之前的改一下。不過第一篇用富文本的竟然沒法換成Markdown了,心衰,繼續丑下去吧。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,466評論 25 708
  • 內容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 46,901評論 22 665
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,537評論 0 17
  • 今天份的實話。 沒錯,就是嫉妒。憑什么在我失控的時候,她可以把持住自己呢? 更討厭的是若無其事的態度,無疑,對這個...
    MYamber閱讀 179評論 0 0
  • 最近喜歡畫起素描來,戴著墨鏡的貓咪是不是很酷呢!下面和大家說一下繪畫步驟吧! 1、用鉛筆起稿,確定好貓咪頭部,身體...
    小韓lucky閱讀 1,100評論 15 33