Android開發學習經驗總結——0基礎自學(持續更新)

更新:寫代碼的好習慣之一就是重構,寫博客也是同樣~小弟來整理一下以前寫的"shit"                            --- 2016年4月9日 html

************************************************************************ java

  我零基礎自學Android,總結的一點經驗,內容有點雜,見諒~~~ android

 0. 關於Android studio更新SDK的問題
git

         入門安卓就幸運地趕上Android studio發佈,因而IDE也就選了AS。 github

        安裝AS以後很重要的一步就是下載SDK,那麼面對一大列的SDK版本問題來了——下載哪一個或者哪些?
web


       答案:下載最新版的SDK,由於它不只擁有最新的功能和更新也能兼容以前全部舊版本。我以前逗比地下載了全部4.0以上的版本,而後····佔了硬盤30個G空間···
算法


1.如何顯示與不顯示ActionBar ?  數據庫


若是Activity class 繼承的是 Activity,沒法顯示ActionBar canvas

已知的一定顯示ActionBar的就是 ActionBarActivity。 瀏覽器

另外在style.xml裏定義theme對ActionBar的樣式也有影響,好比

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">


隱藏ActionBar的Java代碼

if(getActionBar()!=null){
    getActionBar.hide(); 
}
//getActionBar()可能返回的是null,因此須要檢查後再hide


  

   1.1. 全屏加無狀態欄:


requestWindowFeature(Window.FEATURE_NO_TITLE);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);


 

2.OnTouch 方法中的返回值

"True if the listener has consumed the event, false otherwise."

即若是return值設爲trueTouch事件就當作被處理了,不會繼續傳播;若是設爲false,就會繼續傳播當前的Touch事件。

舉個栗子:

myView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(WeatherHomeActivity.this,"Click",Toast.LENGTH_SHORT).show();
            }
        });

   myView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction()==MotionEvent.ACTION_DOWN){
                    Toast.makeText(WeatherHomeActivity.this,"Touch Down",Toast.LENGTH_SHORT).show();
                    return true;
                }
                return false;
            }
        });



以上的代碼裏定義了Onclick的行爲顯示「Click」的Toast,可是OnTouch裏卻在ActionDown的時候就return true,因此每次點擊事件都不會觸發,由於在TouchDown的時候就該Touch事件就已經被消耗不會繼續傳播。(Click的定義是手指按下後收回)。


補充: 

  父子View的得到OnTouch事件的問題——如何只讓子View獲取OnTouch事件,而父View不會獲取?(舉個栗子:父View是個ViewPager,而子View也有左右滑動的效果)。

答案:

使用requestDisallowInterceptTouchEvent()方法。返回值的效果「True if the child does not want the parent to intercept touch events.

 通常用於自定義的View。

再次補充:

  Android 的 View Touch event機制還算有點複雜的,能夠參考這個博客

 http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html


3.  灰色的小提示框 Toast(超好用,超經常使用)

Toast toast = Toast.makeText(this,"Hello world!",Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER,0,0);//設置顯示的位置
toast.show();

補充:

Toast的顯示時間只有SHORT和LONG兩種選擇,可是即便是SHORT的顯示時間也感受挺長的,那麼如何自定義顯示時間?

答案:

用handler計時後主動取消顯示

final Toast toast = Toast.makeText(getApplicationContext(), "This message will disappear in half second", Toast.LENGTH_SHORT);

    toast.show();


    Handler handler = new Handler();

    handler.postDelayed(new Runnable() {

           @Override

           public void run() {

               toast.cancel(); 

           }

    }, 500);


再補充

  在實際應用中,須要看狀況使用Toast。由於Toast顯示時間較短並且不明顯,不適合做爲錯誤反饋,此時使用Alertdialog更合適。



4. findViewById() 用於查找和關聯View(buttonTextViewImageView 等)

補充:

這個對於老手來講太基礎了,但用多了也感受很麻煩,每次都得寫一行代碼來關聯,若是View比較多,致使代碼顯得比較冗雜。用於解決這個問題,有個庫很受歡迎——ButterKnife: (誰用誰知道~)

典型的使用方法:

@Bind(R.id.button1)
  Button button1;

  @Bind(R.id.button2) 
  Button button2;

不只在Activity中可使用,在fragment甚至是RecyclerView的ViewHolder中也能夠,至關便利。

http://jakewharton.github.io/butterknife/



5. Preference的使用

(補充:這是當時看一本書中介紹後寫的筆記,但在實際敲代碼中彷佛不多使用到這些API)

若是要查找Preference中的控件(如,CheckBoxPreferenceEditTextPreference等)用如下方法:

PreferenceManager manager = getPreferenceManager();
CheckBoxPreference password = (EditTextPreference) manager.findPreference("password");


    獲取Preference中的值使用:

PreferenceManager.getDefaultSharedPreferences(context).getString("user","");
//或者分兩步,方便查詢同一個Preference中的多個值
SharedPreferences sharedPreferences =  PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean willMusic = sharedPreferences.getBoolean("music",true);
String username = sharedPreferences. getString("user","");


7.Intent

Intent 類一般是做爲四大組件間的通訊工具,能夠簡單地理解成 「信封」。好比從一個Activity進入到另外一個Activity,能夠在信封中裝入一些信息通知另外一個Activity。

Intent帶上附加值Ertra示例代碼:

發送方

Intent i = new Intent(MainActivity.this,OtherActivity.class);
i.putExtra("icon",data.icon);
startActivity(i);


接收方:

int icon = getIntent().getIntExtra("icon",0);


7.1 發Intent啓動Activity並獲取返回值

須要使用startActivityForResult方法,而且重載onActivityResult方法 如:

Intent intent = new Intent(MyActivity.this, newActivity.class); int requestCode = 110;//本身定義,在返回結果時用來判斷是否本身發出的請求的結果 startActivityForResult(intent,requestCode);



@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK && resultCode ==110){ int weatherCode = data.getIntExtra("weather_code",-1); ... } }


9.  播放音樂


初始化與播放

MediaPlayer mp= MediaPlayer.create(this,R.drawable.fengyanghuagu);//第二個參數是音樂資源id

mp.setLooping(true);//循環播放

mp.setVolume(0.3f,0.3f);//設置音量

mp.start();


結束播放釋放資源


mp.stop();

mp.release();



10.   警示對話提示框AlertDialog

10.1 帶列表的提示框,點擊列表項目啓動對應的事件

AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Your title") .setItems(new CharSequence[]{"add", "update", "delete"}, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //which is the index of the items // ... } }) .show();


10.2 帶文本提示和按鈕的AlertDialog提示框,點擊按鈕選擇發生的事件

AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Your title") .setMessage("想繼續遊戲嗎?") .setPositiveButton("肯定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //... } }) .setNegativeButton("回主菜單", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .show();


10.3  收起Dialog 

dialog.dismiss(); 



11.   防止手機進入休眠狀態

PowerManager.WakeLock wl;
wl = pM.newWakeLock(PowerManager.FULL_WAKE_LOCK,"whatever");
wl.acquire();//啓動休眠鎖
wl.release();//釋放休眠鎖

更多模式參照 http://blog.csdn.net/airk000/article/details/9121003


13.   關於StringBuilder

StringBuilder buf = new StringBuilder();   //使用StringBuilder製做string(因爲要不停地在結尾添加字符,用這個更方便效率更高)

for(int element: puz){
   buf.append(element);
}
  return buf.toString();


補充:

後來有一次刷算法題的時候,起初用String 的 + 方法進行加長字符串,結果顯示運行時間過長,換成了StringBuilder後,大幅縮減了時間。


 

14.   短時音效的使用(如槍聲,按鍵音)

 SoundPool soundPool; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { SoundPool.Builder builder = new SoundPool.Builder(); builder.setMaxStreams(5); soundPool = builder.build(); }else { soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC,0); } int soundId = soundPool.load(this, R.raw.mie, 1); soundPool.setVolume(soundId,1,1); soundPool.play(soundId,1,1,0,0,1);


中止播放釋放資源

soundPool.stop(soundId);
        soundPool.release();


15.   定義Paint的字體

Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG);//反鋸齒畫筆
foreground.setStyle(Style.FILL);  //充滿
foreground.setTextSize(height * 0.75f);  //字體大小
foreground.setTextScaleX(width / height);  //字體高寬比
foreground.setTextAlign(Paint.Align.CENTER);// 字體居格子中間
FontMetrics fm = foreground.getFontMetrics();// Centering in X: use alignment (and X at midpoint)
float x = width / 2;// Centering in Y: measure ascent/descent first
float y = height / 2 - (fm.ascent + fm.descent) / 2;


16.   清除以前的Activity stack 記錄,使返回鍵沒法返回(用於遊戲結束收尾)

Intent i = new Intent(sudu_success.this,happyNewYear.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();


17.   畫圖

  canvas.drawBitmap(happyNY,changeX,changeY,null);

 

18.   延時

try {
     Thread.sleep(1000);
} catch (InterruptedException e) {
     e.printStackTrace();
 }

補充:

以上的方法不是很好,由於會致使線程徹底睡眠,沒法進行其餘的動做。若是隻是打算將某個動做延時進行的話,可使用handler的postDelay()方法



19.   多線程        

Thread sleeper = new Thread(){
            public void run(){
                try {
                    sleep(1200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        sleeper.start();
        try {
            sleeper.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


20.   作混合應用的時候webview 添加JavascriptInterface js掉用方法 出現undefined 調試了一下午終於找到緣由:

在綁定的方法前必定要加

@JavascriptInterface

不然在某些手機(好比紅米)webview中會出現調用方法時undefined的狀況



21. Android Studio  的經常使用快捷鍵 (Mac 和 Windows上略有不一樣,坑!)

Alt+回車 導入包,自動修正


Ctrl+P 方法參數提示


Ctrl+X 刪除行


Ctrl+D 複製行


Ctrl+/ 或 Ctrl+Shift+/  註釋(// 或者 )


Ctrl+J  自動代碼


Alt+1 快速打開或隱藏工程面板


Alt+ Up/Down 在方法間快速移動定位


F2 或Shift+F2 高亮錯誤或警告快速定位

ctrl + alt + L 代碼自動排版


22. 自定義的View,文字和代碼有點多,詳見我另外一篇文章——

http://my.oschina.net/Bruce370/blog/385146


23. 使用handler進行計時和操做,文字和代碼有點多,詳見我另外一篇文章

http://my.oschina.net/Bruce370/blog/385155


24. 改變drawline的線條粗細 

setStrokeWidth(float width) 函數

Paint darkPaint = new Paint();//聲明畫筆
darkPaint.setColor(getResources().getColor(R.color.midnightblue));//設置顏色

darkPaint.setStrokeWidth(5);//設置畫筆粗細



25.關於簡化代碼。

無心中發現Android studio竟然有智能簡化代碼的功能——

我本來的代碼是(請觀衆原諒個人渣代碼):

if (puz[i] != 0) 
nochange[i % 9][i / 9] = true;
 else 
nochange[i % 9][i / 9] = false;


在我打算commit and push到GitHub時,出現一些warnings,其中一個提示我這幾行代碼可以簡化,我單擊簡化後獲得如下代碼:

nochange[i % 9][i / 9] = puz[i] != 0;


人生第一次被開發工具鄙視和調戲了···


26. 關於LongClick的調用

收到LongClick的調用後還會調用click嗎? 
這個要根據LongClick listener的返回值來決定。


lv.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
	System.out.println("Item LONG clicked. Position:" + position);
	return false;
	}
});

若是返回false那麼click仍然會被調用。並且是先調用Long click,而後調用click。 

若是返回true那麼click就會被吃掉(consumed),click就不會再被調用了。


27. 關於查看Android的API文件

  寫一些函數常常得查閱API文檔,瞭解參數和用途什麼的,可是發現即便是下載到本地的API文檔,用瀏覽器打開瀏覽也很卡。剛剛找到的解決辦法——禁止瀏覽器使用Javascript。在全部API的html文檔裏,都有JavaScript鏈接到google服務器的一些資源,但在我大天朝訪問google是件不容易的事情,所以瀏覽器會屢次嘗試鏈接並等待迴應,因此體驗以爲很卡。

建議使用FireFox瀏覽器,禁用和從新開啓JavaScript很方便,以下圖:

關了以後,瀏覽起API簡直飛快!

後續:  若是一開始就禁用JavaScript,會致使左側的導航欄沒法滾動,沒法查看後面的內容

所以,建議先保持開啓JavaScript,打開了API的某一頁(好比packages.html這頁),此時左側導航欄可以正常滾動。而後禁用JavaScript,而全部後續查看的頁面都在新的頁面打開。


28. 數據持久化——首選項+內部存儲+外部存儲+數據庫

http://my.oschina.net/Bruce370/blog/419907


29. assets文件夾在android studio中的位置

assets文件夾在android studio中的位置和在Eclipse不同,位於src\main目錄下


30. 使用系統的content provider

http://my.oschina.net/Bruce370/blog/420894

  自定義的content provider

http://my.oschina.net/Bruce370/blog/420919


31.關於如何使用 Broadcast Receiver


Android發送和接收短信(Broadcast receiver的一個使用例子)

http://my.oschina.net/Bruce370/blog/421769


32.如何偵測EditText的內容變化

--使用addTextChangedListener方法:

input_edittext.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
               // Log.d("edit_text_change","-------------------- beforeTextChanged-----------------");
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
               // Log.d("edit_text_change","-------------------- onTextChanged-----------------");
            }

            @Override
            public void afterTextChanged(Editable s) {
               // Log.d("edit_text_change","--------------------  afterTextChanged-----------------");
                if(input_edittext.getText().toString().isEmpty()){
                    record_button.setBackgroundResource(R.drawable.record_imagebtn);
                }else {
                    record_button.setBackgroundResource(R.drawable.text_imagebtn);
                }
            }
        });
以上代碼例子意在實現一個功能——在EditText對象的內容被更改了以後,檢測內容是否爲空,根據結果對應地設置另外一個按鈕的背景圖片。(好比QQ聊天輸入框爲空的時候,右側按鈕爲一個麥克風圖樣,有內容的時候爲一個「發送」字樣)


33.關於背景選擇器selector的易錯點

http://my.oschina.net/Bruce370/blog/425936


34.適用於拉伸的特殊圖片 nine-patch

http://my.oschina.net/Bruce370/blog/424614


35.安卓Notification的幾個常見難點

http://my.oschina.net/Bruce370/blog/472117


36. 安卓開發中,動畫也是很經常使用的。

http://my.oschina.net/Bruce370/blog/493268


37.安卓開發中枚舉的使用。

   官方文檔說明,安卓開發應避免使用Enum(枚舉類),由於相比於靜態常量Enum會花費兩倍以上的內存...

  http://my.oschina.net/Bruce370/blog/499279


38.根據資源名字獲取資源ID

  好比,有10個String資源分別叫作「關卡1」,「關卡2」...「關卡10」,分別存放了10個關卡的名字。如今須要用遍歷的方式將這十個名字找出來(好比在listview裏顯示),怎麼辦呢?

for(int i = 1;i < 11; i++){
  //獲取對應的String資源的ID
  int strId = context.getResources().getIdentifier("關卡"+i, "string", context.getPackageName());

  //取得ID後,天然就方便獲取String的內容了
  String name = context.getString(strId);

  ...

}
getIdentifier()這個方法能夠拿全部資源類型的ID,只須要改變第二個參數


詳參:http://developer.android.com/reference/android/content/res/Resources.html#getIdentifier(java.lang.String, java.lang.String, java.lang.String)



(``````````` 感謝收藏這篇文章的朋友們,出於方便搜索考慮,我決定將一些內容分紅多篇文章寫,在這裏只留連接········································································································)

相關文章
相關標籤/搜索