Android初級躲不開的那些坑

OCN_Yang發表於2017-12-14

Android初級躲不開的那些坑

Android_Note

這裡是作者(OCN.Yang)在Android初級階段遇到的那些坑坑窪窪,有些還是開發中要知道的小技巧。相信大多數初學者難免也會遇到相同的坑,大家大概看看有者避之,還沒遇到的就躲之。大牛和已經進階的朋友可以繞道(相信你們很忙的)。

這篇部落格首發在我的個人部落格網站 www.ocnyang.com

原文地址

1、Ctrl + O快捷鍵

檢視程式碼的大綱 即類的方法列表。

2、layout_weight

  • android:layout_weight的真實含義是:
    一旦View設定了該屬性(假設有效的情況下),那麼該 View的寬度等於原有寬度(android:layout_width)加上剩餘空間的佔比!
  • 如果width設定了match_parent ,那麼,加上的是負的長度(相當於減去一部分長度)
  • 如果width設定了warp_content ,那麼,剩餘空間是“父容器總長度”減去“元件的內容佔的長度”,然後再按比重值分。

3、Background=”@null”

可以給背景設定一個null值,在一定情況下這樣做是有必要的。

4、判斷String是否為空

TextUtils.isEmpty(String str) 
複製程式碼

5、Int/int 還是等於整型,太容易出錯了。

6、LinearLayout中的orientation & gravity

當LinearLayout佈局中設定**orientation="vertical"**屬性:

  • 如果子元件設定**layout_gravity="center_vertical"**是無效的;
  • 如果LinearLayout中設定**gravity="center_vertical"**是可以起到作用將子元件垂直居中的。水平佈局同理

7、單例項模式的Activity

設定為單例項模式(singleInstance)的Activity,會單獨開一個任務棧單獨存放這個activity,這個任務棧只會在程式退出後消除。

8、選擇手機中的圖片並顯示在ImageView上

Intent intent = new Intent();  
/* 開啟Pictures畫面Type設定為image */  
intent.setType("image/*");  
/* 使用Intent.ACTION_GET_CONTENT這個Action */  
intent.setAction(Intent.ACTION_GET_CONTENT);   
/* 取得相片後返回本畫面 */  
startActivityForResult(intent, 1);  
            
  
@Override  
protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (resultCode == RESULT_OK) {  
        Uri uri = data.getData();  
        ContentResolver cr = this.getContentResolver();  
        try {  
            Bitmap bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));  
            ImageView imageView = (ImageView) findViewById(R.id.iv01);  
            /* 將Bitmap設定到ImageView */  
            imageView.setImageBitmap(bitmap);  
        } catch (FileNotFoundException e) {  
            Log.e("Exception", e.getMessage(),e);  
        }  
    }  
    super.onActivityResult(requestCode, resultCode, data);  
} 
複製程式碼

9、notifyDataSetChanged() 重新整理Adaper.

10、ListView 的優化

主要方法:

  1. ListView設定固定高度,
  2. convertView判空,
  3. SetTag:convertView.setTag(viewHolder),
  4. 內部類ViewHolder,
  5. 分頁載入

11、R檔案編譯報錯 & 找不到ID報錯

R檔案的編譯原理:當資原始檔或id命名中其中一個檔案的命名不滿足規範時,R檔案整體就不會再編譯。

12、列表裡的CheckBox

Android初級躲不開的那些坑
注意: Spinner:如果item中有能夠獲得焦點的控制元件(例如CheckBox),則在item獲得點選事件之後會繼續傳遞給能夠獲得焦點的控制元件.
想讓item在被點選後Spinner收回去,需要在佈局(例如LinearLayout)中加上屬性後代是否可以獲得焦點:

android:descendantFocusability="blocksDescendants"//阻止後代獲得焦點  
複製程式碼

13、獲取xml資原始檔中定義的陣列

getResources().getStringArray(R.array.city)  
複製程式碼

14、安卓預設字型大小:

Android初級躲不開的那些坑

15、java 字串split有很多坑

Java程式碼

System.out.println(":ab:cd:ef::".split(":").length);//末尾分隔符全部忽略    
System.out.println(":ab:cd:ef::".split(":",-1).length);//不忽略任何一個分隔符    
System.out.println(StringUtils.split(":ab:cd:ef::",":").length);//最前面的和末尾的分隔符全部都忽略,apache commons    
System.out.println(StringUtils.splitPreserveAllTokens(":ab:cd:ef::",":").length);//不忽略任何一個分隔符 apache commons     
輸出:    
4    
6    
3    
6    
複製程式碼

看了下jdk裡String類的**public String[] split(String regex,int limit)**方法,感覺平時不太會用這方法,以為在用正規表示式來拆分時候,如果匹配到的字元是最後一個字元時,會拆分出兩個空字串,
例如"o"split("o",5) or "o"split("o",-2)時候 結果是"" "" 也就是下圖中紅框裡的內容,所以平時一般都用split(String regex) 方法,其實也就等同於split(String regex,0)方法,把結尾的空字串丟棄!

Android初級躲不開的那些坑

16、Android Studio 的全域性變數和強轉的快捷鍵

  • Findviewbyid(R.id.XXX).cast(強轉轉換) 強轉後點選回車回到行尾
  • .field 全域性變數
  • .var 區域性變數

17、TextView新增滾動條

Android初級躲不開的那些坑

18、陣列介面卡

Android初級躲不開的那些坑

////xListView上滑重新整理,下滑載入更多///swapListView側滑刪除/

19、Viewstub

只能inflatay一次。不然會報錯。

20、補間動畫的旋轉的圓心計算方法

以圖片的左上角為座標(0,0),分別計算出pivotX和pivotY的數值:50%是圖片本身大小的一半,50%p是父窗體寬高的一半長度。然後在圖片的左上角的基礎上加上這兩個陣列

Android初級躲不開的那些坑

位移也是同樣的計算方式

21、外掛

ButterKnife Gosn android.selector.generat

22、margin & padding

android 中的控制元件的margin 和 padding 都是不會影響控制元件的設定寬高。(這點和網頁設計是不一樣的)

23、R檔案出錯。

當佈局或id報找不到的錯時,可能就是R檔案出錯。

  • 一種可能是你匯入了命名不規範的資原始檔,導致R檔案不能自動編譯了。
  • 一種可能是你匯入了import android.R系統的R檔案導致報錯

24、ListView的多型別item

自定義ListView中,如果item採用多種型別的佈局。那麼在getItemType中的下標一定要從0開始。不然會報下標越界異常。

25、java怎麼在一個字串裡擷取一個正規表示式欄位

public static void main(String[] args) {
    String str = "<div><h3 ..>dsijiswer*dfhjgf</h3></div><table><h3>sdsd</h3></table>";
    Pattern p = Pattern.compile("<h3.*?/h3>");
    Matcher m = p.matcher(str);
    while (m.find()) {
        System.out.println(m.group());
    }
}
複製程式碼

26、事件機制:分發 消費 電梯機制:向上分發 ,向下消費

27、LinearLayout內部子控制元件之間的間隔 設定為等同的

在drawer資料夾下建立一個shape的圖形檔案

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <size android:width="15dp" />
    <solid android:color="@android:color/transparent" />
</shape>  
複製程式碼

在linearLayout裡設定屬性divider為上圖形,同時設定showdivider屬性

28、TextView 上設定的圖片 設定圖片大小的方法:

txtZQD = (TextView) findViewById(R.id.txtZQD);  
Drawable[] drawable = txtZQD.getCompoundDrawables();  //獲取它前後左右的圖片
// 陣列下表0~3,依次是:左上右下  
drawable[1].setBounds(100, 0, 200, 200);  
txtZQD.setCompoundDrawables(drawable[0], drawable[1], drawable[2],drawable[3]);  
複製程式碼

29、android中內部儲存和外部儲存的理解和路徑獲取

Android初級躲不開的那些坑

30、自定義組合控制元件

在載入佈局的時候要用 View.inflate(context,R.layout.img_share,this);
或者 LayoutInflater.from(context).inflate(R.layout.img_share,this);
不能用 LayoutInflater.from(context).inflate(R.layout.img_share,null);這樣載入不上。

31、foreground 前景色生效

Android初級躲不開的那些坑

32、新增第三方依賴報錯

Android初級躲不開的那些坑

配置錯誤原因:1、導包有誤。2、少導包。3、重複導包。

33、佈局裡的ListView|GridView搶佔焦點

Scrollview裡巢狀Gridview,Gridview搶焦點問題(顯示佈局的時候老是先從Gridview的第一個item顯示)

解決方法:在獲取inflate view之後,程式碼給GridView.setFocusable(false)就可以了

這裡的listview的item裡巢狀了橫向滑動的scrollview的gridview,

同樣的問題,同樣的解決方案:在listview的adapter中在載入完item之後對gridview設定setFocusable(false)。 這裡需要注意的是,是在搶焦點的列表的父容器建立之後就對列表設定取消焦點。

例如:
在ListView中巢狀GridView中:

convertView = LayoutInflater.from(mContext).inflate(R.layout.item_listview_home, null);
viewHolder = new ViewHolder(convertView);
viewHolder.mGridIilh.setFocusable(false);  
複製程式碼

在fragment佈局中存在列表搶佔焦點:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_cheapsale, null);
    ButterKnife.inject(this, view);
    mGridFragmentCheapsale.setFocusable(false);  
複製程式碼

在Activity佈局中存在列表搶佔焦點:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sale);
    ButterKnife.inject(this);
    mListviewHome.setFocusable(false);
複製程式碼

34、列表搶佔焦點問題

在gridview和listview初始化資料時自動呼叫或者我們顯示呼叫notifyDataSetChanged的時候第一個item會被選中並會搶焦點。
android4.4在呼叫notifyDataSetChanged的時候註釋掉了判斷touchmode的程式碼,導致一呼叫notifyDataSetChanged就模擬使用者點選了gridview。
我們繼承gridview或者listview重寫裡面的isInTouchMode方法:

[java] view plaincopy
/** 
 * 遮蔽android4.4 setAdapter時View搶焦點的BUG 
 */  
@Override  
public boolean isInTouchMode() {  
    if(19 == Build.VERSION.SDK_INT){  
        return !(hasFocus() && !super.isInTouchMode());  
    }else{  
        return super.isInTouchMode();  
複製程式碼

35、去除Listview滾動背景變黑,item點選預設背景

listview預設背景和系統視窗一樣是透明的,如果給listview加上背景圖片,或者背景顏色時,滾動時listview會黑掉,因為滾動時,列表裡面的view重繪用的依舊是系統預設的透明色,顏色值為#FF191919
解決辦法:

  • 呼叫listview的setCacheColorHint(0),顏色值設定為0
  • 設定xml檔案中listView的屬性
    Android:cacheColorHint="#00000000",滾動時,重繪View的時候就不會有背景顏色。
    android:listSelector="#00000000" 進行上面的設定之後,ListView點選item時就沒有任何現象了

36. 開啟Android系統程式設定頁面

Intent intent = new Intent();
intent.setClassName("com.android.settings","com.android.settings.ManageApplications");
intent.setAction("android.intent.action.MAIN");
try {
    startActivity(intent);
} catch (Exception e) {
    e.printStackTrace();
}  
複製程式碼

37、禁止EditText自動獲取佈局焦點

解決之道:在EditText的父級控制元件中找一個,設定成

android:focusable="true"  
android:focusableInTouchMode="true"  
複製程式碼

這樣,就把EditText預設的行為截斷了!

38、RadioButton設定預設選中

如果RadioGroup中設定預設選中一個RadioButton後,在選擇時會選中兩個的問題
解決方法:
不需要設定RadioButton的預設選中, 這樣會使RadioButton一直處於選中狀態.
我們應該給RadioGroup設定選中的RadioButton,
也就是說把radioButton.setCheck(true);
更改為radioGroup.check(radioButton.getId());

39、實現ImageView寬度填滿螢幕,高度自適應

1、自定義ImageView重寫View的onMeasure方法

public class ResizableImageView extends ImageView {  
  
    public ResizableImageView(Context context) {  
        super(context);  
    }  
  
    public ResizableImageView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    }  
  
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){  
        Drawable d = getDrawable();  
  
        if(d!=null){  
            // ceil not round - avoid thin vertical gaps along the left/right edges  
            int width = MeasureSpec.getSize(widthMeasureSpec);  
            //高度根據使得圖片的寬度充滿螢幕計算而得  
            int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());  
            setMeasuredDimension(width, height);  
        }else{  
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
        }  
    }  
  
}  
複製程式碼

2、設定ImageView的屬性

//寬度填滿螢幕
android:layout_width=”match_parent”
android:scaleType=”fitXY”
android:layout_height=”wrap_content”
//保持比例,一定要設定
android:adjustViewBounds=”true”
複製程式碼

40、Glide載入網路圖片填充到39中的ImageView中

因為Glide載入圖片的規則是根據imageview的大小調整圖片。但是ImageView的大小為ImageView寬度填滿螢幕,高度自適應的時候,Glide載入的圖片就會顯示不出來,為此我們選擇了一種迂迴的方式載入:先請求圖片為bitmap,這個時候圖片就有一定的尺寸了,再設定到ImageView中就可以自適應了:

Glide.with(GraphicDetailsFragment.this)
                    .load((new StringBuffer(Const.URL_HEAD).append(mStringList.get(position))).toString())
                    .asBitmap()
                    .into(new SimpleTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                            viewHolder.mImageView.setImageBitmap(resource);
                        }
                    });
複製程式碼

41、Android GridView元件如何去除四周的空隙

設定GridView的android:listSelector屬性 android:listSelector="@null" 設定後四周空隙就消除了

42、主題檔案設定的顏色

Android初級躲不開的那些坑

Android初級躲不開的那些坑

43、ListView設定item的行間距,以及去掉分割線

1.設定item的行間距:
可以在xml佈局檔案中的listView下設定xml屬性:
android:divider="#00000000"
android:dividerHeight="18dp"

解釋:分隔線透明,高度為18dp。

2.去掉item之間的分割線:
每個item之間都有分割線,如果單純想去掉分割線,方法還是很多的:

  • 法1:設定android:divider="@null"
  • 法2:android:divider="#00000000"
  • 法3:setDividerHeight(0);高度設為0 || ListView.setDivider(null);
  • 法4:android:divider="@drawable/listview_horizon_line"

3.隱藏頭部分隔線
listview分割線會在頭部、資料item、及根部的底部列印,如果要取消頭部分割線必須 先設定其方法

addHeaderView(headView, null, true);
addFooterView(footView, null, true);  
複製程式碼

注意:第三個引數必須為true,否則無效

//顯示頭部出現分割線
listview.setHeaderDividersEnabled(true);
//禁止底部出現分割線 
listview.setFooterDividersEnabled(false);  
複製程式碼

44、Error:Failed to create directory

今天android stutio出現
Error:Failed to create directory'C:\Users\Administrator\.gradle\caches\2.8\scripts\ijinit7_5jx13p26aqkoramvuhfn0lqca\init\classes'
這個問題,解決的辦法是:
File 下面有個 Invalidate Caches/Restart ,彈出一個框,點選 Invalidate and Restart 按鈕,等待重啟就OK了。

45、TextView追加字串

TextView.append(CharSequence text);//在現有字串的基礎上向字串快取區追加字串;(自己想法:可能會在重新整理頁面的時候造成多次重複追加,所以不提倡使用)  
複製程式碼

46、Fragment巢狀Fragment要用getChildFragmentManger();

疑問:兩個巢狀,fragment給第二個Fragment通過setArguments(bundle)傳值,傳遞不過去。

47、隱藏ListView滾動條

setScrollbarFadingEnabled(true);
//不活動的時候隱藏,活動的時候顯示

setVerticalScrollBarEnabled(true);
//不活動的時候隱藏,活動的時候也隱藏
複製程式碼

android: scrollbars="none"與 setVerticalScrollBarEnabled(true); 效果一樣。

48、解決滑動衝突帶來的問題

重寫ListView的onMeasure的方法來解決滑動衝突的應用中,ListView是不能設定divider和高度的,如果設定了,最後一個item顯示不全,這是因為onMeasure在根據條目設定ListView的高度時並沒有把divider的高度設定進去。

49、匯入第三方庫的錯誤

Error:Cannot change dependencies of configuration ':app:_debugAnnotationProcessor' after it has been resolved.

當匯入一個第三方庫的時候報的錯誤。是因為這個庫依賴的某些庫版本過高而你的Android studio沒有下載這個庫。

50、ScrollView的高度

ScrollView中沒有match_parent這麼一說,相當於它內部的控制元件高度是沒有參考物的。match_parent的失效,它會表現成為wrap_content。

51、Java思維導圖

Java思維導圖

52、Rxjava思維導圖

Rxjava思維導圖

53、MVP結構圖

MVP簡單結構圖

55、onPrepareOptionsMenu 和onCreateOptionsMenu 的區別

在android中建立選單menu時需要重寫Activity的onCreateOptionsMenu(Menumenu)方法,這個方法只在第一次建立的時候呼叫一次,所以如果之後想對menu進行動態的修改,那麼就不能再對onCreateOptionsMenu做什麼手腳,就要用到onPrepareOptionsMenu(Menumenu)方法了。

onPrepareOptionsMenu與onCreateOptionsMenu不同的是,他在每次按下menu硬鍵之前會被呼叫,所以可以在這裡動態的改變menu。

注意:在onPrepareOptionsMenu(Menumenu)函式中,首先需要呼叫:

super.onPrepareOptionsMenu(menu);
menu.clear();
複製程式碼

如果沒有clear而直接add的話,那麼選單中選單項是會“追加”的,這樣隨著你不停的點menu鍵,選單項就不停的增加。

另外,android系統預設的選單樣式是支援最多3個一行,如果有4項就每行2個有2行...如果想自定義樣式,可以使用xml檔案定義樣式。

56、android:parentActivityName

一個Activity在manifet裡宣告瞭Android:parentActivityName;這時候通過Activity左上角的返回按鈕點選返回,啟動宣告的父Activity,並且總會先呼叫父Activity的OnDestroy方法,點選子Activity的左上角返回按鈕的時候,呼叫邏輯如下:

MainActivity.onDestroy();
MainActivity.onCreate(null);
MainActivity.onStart();
複製程式碼

解決方案是: 為設定MainActivity屬性android:launchMode=singleTop (這個大概的意思是,消除先呼叫Destroy方法的解決方案)

順便腦補android:parentActivityName的作用,就是為了左上角給子Activity加一個返回按鈕,具體資訊如下:

Android 4.1 提高效能、增強使用者體驗
  App 棧導航:通過設定 android:parentActivityName 改變回退棧的內容,如果棧中沒有 parentActivity,則合成棧,通過 onPrepareNavigateUpTaskStack() 改變 parentActivity 中的內容。

57、條件編譯

條件編譯(C裡面的概念)是個好東西,但是在java體系中卻沒有這樣的預定義。但是我們可以根據java編譯時對程式碼的優化機制實現條件編譯。
java在編譯中有這樣一條原則:“編譯器會對程式碼進行優化,對於條件永遠為false的語句,JAVA編譯器將不會對其生成位元組碼。”
這樣一來,我們只需要在Const(靜態變數類)中定義一個isDebug的布林變數,然後對想要進行條件編譯的程式碼用

if(isDebug){
    ...程式碼語句...
}  
複製程式碼

包含起來。這樣你可以通過控制isDebug的值實現條件編譯。當isDebug為false時,if條件內的...程式碼語句...會被編譯器忽略,也就是不會生成對應的位元組碼。

58、動態設定ImageView的圖片路徑

//實現的原理是 java的反射?
int resId = (Integer) R.drawable.class.getField("icon").get(null);  
holder.img.setImageResource(resId);    
複製程式碼

需要明白的一點就是 每一張圖片的name 都是 R.drawable的一個欄位

59、顏色列表的靜態儲存

在Values下建立陣列檔案:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--適合白色字型的彩虹色-->
    <integer-array name="itemcolor">
        <item>0xFF79429D</item>
        <item>0xFF5691F5</item>
        <item>0xFF76BA55</item>
        <item>0xFFB3E0E0</item>
        <item>0xFF27C9C2</item>
        <item>0xFF92AD6B</item>
        <item>0xFFEC4F4F</item>
        <item>0xFFEE6593</item>
        <item>0xFFFFAC5A</item>
        <item>0xFF6296AF</item>
        <item>0xFFBF8A28</item>
        <item>0xFF319388</item>
    </integer-array>
</resources>
複製程式碼

這裡需要注意的是顏色的數值必須是8位,即前兩位的透明位不能省略。 然後就可以獲取

Resources resources = context.getResources();
mColorArray = resources.getIntArray(R.array.itemcolor);
...
setBackgroundColor(R.id...., mColorArray[Position % mColorArry.length]);
複製程式碼

60、ScrollView 顯示不全

有時候 ScrollView 巢狀 LinearLayout 時會有顯示不全的情況,這個時候應該看看 ScrollView 的父佈局是不是用的 CoordinatorLayout。
當外部用 CoordinatorLayout 時,內部應該用 NestedScrollView ,不然會產生不確定的 bug。
同樣在 CoordinatorLayout 內部使用 ViewPager & TabLayout 來顯示不同的 Fragment 時,如果 Fragment 內使用 ScrollView 也會有顯示不全的情況。

61、神奇的 * / 運算優先順序

double sin20 = Math.sin(Math.PI * 20 / 180); //0.3420201433256687 double sin201 = Math.sin(20 / 180 * Math.PI); //0.0

找到原因了,當先計算20/180的時候是按int型別運算的,得到的結果是0。所以最後結果為0.

62、Alertdialog對話方塊,設定點選其他位置不消失

Android4.0 以上 AlertDialog 在觸控對話方塊邊緣外部,對話方塊消失
可以設定這麼一條屬性,當然必須先AlertDialog.Builder.create()之後才能呼叫這兩個方法
方法一:
setCanceledOnTouchOutside(false); 呼叫這個方法時,按對話方塊以外的地方不起作用。按返回鍵還起作用
方法二:
setCancelable(false); 呼叫這個方法時,按對話方塊以外的地方不起作用。按返回鍵也不起作用

63、關於 Vector 你需要注意的事情

當你的專案中用到用 Vector 圖形時,請注意事項可以參考www.jianshu.com/p/e3614e7ab…
另外值得注意的是

//mDrawableActive = ContextCompat.getDrawable(context, R.drawable.vec_checkbox_fill_circle_outline);
//mDrawable = ContextCompat.getDrawable(context, R.drawable.vec_checkbox_blank_circle_outline);

//解決 vector “資源未找到” 錯誤,可以考慮用一下方法代替
try {
    mDrawableActive = AppCompatDrawableManager.get()
            .getDrawable(context, R.drawable.vec_checkbox_fill_circle_outline);
    mDrawable = AppCompatDrawableManager.get()
            .getDrawable(context, R.drawable.vec_checkbox_blank_circle_outline);
} catch (Resources.NotFoundException notFoundException) {
    Logger.e(notFoundException.getMessage());
} catch (Exception e) {
    Logger.e(e.getMessage());
} finally {
    mDrawableActive = context.getResources().getDrawable(R.drawable.vec_checkbox_fill_circle);
    mDrawable = context.getResources().getDrawable(R.drawable.vec_checkbox_empty_circle);
}  
複製程式碼

同時需要注意的是:使用Vector時好像不能關閉硬體加速:

android:hardwareAccelerated="false"//不要在配置檔案中使用這個設定
複製程式碼

64、OOM 記憶體溢位

當你在測試應用時,如果在部分機型上執行正常,而在部分機型上出現 OOM ,除了對應用再次做各種優化外,你可以在配置檔案中加上:

<application
    ...
    android:largeHeap="true"
    ...
    />
複製程式碼

說不定就好了呢。

65、Toolbar 左側有空白(內邊距)

引起原因:
在V7包下,Wiget.AppCompat.Toolbar的parent中,contentInsetStart(預設的有值)這個屬性就是引起自定義ActionBar不能完全填充的原因。

<style name="ClubToolbar" parent="Widget.AppCompat.Toolbar">  
        <item name="contentInsetStart">0dp</item><!-- 設定該屬性解決空白部分-->  
</style>  
複製程式碼

然後在AppStyle中(一定在這,單獨在Toolbar的style中設定不起作用)重寫Toolbar的屬性:

<item name="toolbarStyle">@style/ClubToolbar</item>  
複製程式碼

66、DrawerLayout 的使用小點

DrawerLayout.setDrawerListener(new ActionBarDrawerToggle);//有動畫效果的選單圖示 DrawerLayout.setScrimColor(Color.TRANSPARENT) //去除側滑時的陰影遮罩效果

在一定版本中的NavigationView的都是有半透明效果的
如果不需要可以通過設定下面屬性去除:

app:insetForeground="@android:color/transparent"
複製程式碼

同時如果想要Nav在使用中沒有背景全透明直接設定背景為#00000000;同時去除 headerLayout 的背景即可。

67、TextView 一個原生的Bug

使用 SDK:15~25 測試版本:Android 6.0;Android 4.3(在這兩個版本上都存在,中間版本一定也存在)

<!--這裡只給父佈局 LinearLayout 設定的點選事件,其他控制元件沒有設定任何監聽事件-->
<LinearLayout
    android:id="@+id/linearlayout"
    android:layout_width="match_parent"
    android:layout_height="35dp"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="Time"/>

    <TextView
        android:id="@+id/time_value"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inputType="date"/>
</LinearLayout>
複製程式碼

一次無意中發現的。如果給 TextView 設定一個 inputType 屬性,按理說,inputType 應該是不起作用的,但是這裡將會存在一個神奇的事情(不知道算不算一個原生bug):

  1. 如果此時你給父佈局(如上面的 @id/linearlayout)設定點選事件,當你在 @id/time_value 區域點選的話,不會有任何反應,點選在其他區域比如 @id/time 正常。(其他控制元件沒有設定任何監聽事件)
  2. 如果長按 @id/time_value 區域,將會出現游標(不能編輯)同時出現貼上按鈕提示,點選貼上按鈕,能夠貼上上並顯示貼上的文字。(除父佈局沒有設定其他任何監聽事件)

68、ListView、RecyclerView、ScorllView、Viewpager 等等,取消頂部半圓形的拉力紋

android:overScrollMode="never"
複製程式碼

69、EditText 顯示兩行的高度

android:inputType="textMultiLine" //可以顯示多行
android:gravity="left|top" //輸入時游標左上角
android:minLines="6" //最小顯示6行
複製程式碼

70、.9圖片

左邊和上邊的黑邊表示拉伸區域。右邊和下邊的黑邊表示填充區域

71、NavigationView 獲取 HeaderLayout 佈局裡的控制元件

其實,NavigationView是一個RecyclerView(在23.1.0版本之前是ListView),header佈局通常是0號元素。在Support Library v23.1.1版本中,可以使用如下方法很方便地獲取到header中的view:

View headerLayout = navigationView.getHeaderView(0); // 0-index header
複製程式碼

而在23.1.0版本中,就需要通過這種方法:

View headerLayout =
navigationView.inflateHeaderView(R.layout.navigation_header);
panel = headerLayout.findViewById(R.id.viewId);
// panel won't be null
複製程式碼

72、Edittext 輸入的限制

限制只輸入某些值包括數字、字母等

android:digits="0123456789abcdefghigklmnopqrstuvwxyz"  
複製程式碼

上面這行程式碼可以是你任何的限制,只能輸入什麼就到裡面寫就可以了,上面寫的是隻可以輸入數字和字母。

android:inputType="textPassword"  
android:digits="0123456789abcdefghigklmnopqrstuvwxyz"  
複製程式碼

這裡是只能輸入數字和字母並且是密碼格式,這兩個設定並沒有衝突, android:inputType="textPassword" 這裡是文字,是可以輸入中文的,但是要是你加了 android:digits="0123456789abcdefghigklmnopqrstuvwxyz" ,inputType 這裡的中文就會失效了,但是 password 不會失效,這裡只是打個比方,大家都懂的。

inputType的屬性值

android:inputType="none"  
android:inputType="text"  
android:inputType="textCapCharacters" 字母大寫  
android:inputType="textCapWords" 首字母大寫  
android:inputType="textCapSentences" 僅第一個字母大寫  
android:inputType="textAutoCorrect" 自動完成  
android:inputType="textAutoComplete" 自動完成  
android:inputType="textMultiLine" 多行輸入  
android:inputType="textImeMultiLine" 輸入法多行(如果支援)  
android:inputType="textNoSuggestions" 不提示  
android:inputType="textUri" 網址  
android:inputType="textEmailAddress" 電子郵件地址  
android:inputType="textEmailSubject" 郵件主題  
android:inputType="textShortMessage" 短訊  
android:inputType="textLongMessage" 長資訊  
android:inputType="textPersonName" 人名  
android:inputType="textPostalAddress" 地址  
android:inputType="textPassword" 密碼  
android:inputType="textVisiblePassword" 可見密碼  
android:inputType="textWebEditText" 作為網頁表單的文字  
android:inputType="textFilter" 文字篩選過濾  
android:inputType="textPhonetic" 拼音輸入 //數值型別  
android:inputType="number" 數字  
android:inputType="numberSigned" 帶符號數字格式  
android:inputType="numberDecimal" 帶小數點的浮點格式  
android:inputType="phone" 撥號鍵盤  
android:inputType="datetime" 時間日期  
android:inputType="date" 日期鍵盤  
android:inputType="time" 時間鍵盤  
複製程式碼

73、跳轉activity,清空之前activity棧

問題描述:
開發中,遇到退出登入時,需要將介面跳轉到登入介面,並將棧中所有Activity清空。

解決辦法

Intent intent = new Intent(A.this,B.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);  
startActivity(intent);  
複製程式碼

startActivity 的時候傳遞 FLAG_ACTIVITY_CLEAR_TASK 這個標誌,那麼這個標誌將會清除之前所有已經開啟的 activity .然後將會變成另外一個空棧的 root ,然後其他的 Activitys 就都被關閉了.這個方法必須跟著 {@link #FLAG_ACTIVITY_NEW_TASK} 一起使用.

74、LayoutInflater.from(...).inflate(...) 的引數講解

inflate(int resource, ViewGroup root, boolean attachToRoot)  
複製程式碼
  1. 如果root為null,attachToRoot將失去作用,設定任何值都沒有意義。
  2. 如果root不為null,attachToRoot設為true,則會給載入的佈局檔案的指定一個父佈局,即root。
  3. 如果root不為null,attachToRoot設為false,則會將佈局檔案最外層的所有layout屬性進行設定,當該view被新增到父view當中時,這些layout屬性會自動生效。
  4. 在不設定attachToRoot引數的情況下,如果root不為null,attachToRoot引數預設為true。

大大小小的坑,無處不在,防不勝防。後續會繼續更新這篇博文的。

點選檢視更多Android技術文章

本部落格是作者(OCN.Yang)原創
轉載請標明原地址:ocnyang.com/2016/08/31/…

相關文章