Android开发学习经验总结——0基础自学(持续更新)

  我零基础自学Android,总结的一点经验,内容有点杂,见谅~~~

      0. 关于Android studio更新SDK的问题

         入门安卓就幸运地遇上Android studio发布,于是IDE也就选了AS。

        安装AS之后很重要的一步就是下载SDK,那么面对一大列的SDK版本问题来了——下载哪个或者哪些?

       答案:下载最新版的SDK,因为它不仅拥有最新的功能和更新也能兼容之前所有旧版本。我之前逗比地下载了所有4.0以上的版本,然后····占了硬盘30个G空间···


1.       如何显示与不显示ActionBar ?

(如今google更提倡使用toolbar代替ActionBar,小弟找个时间去学习学习)

如果Activity class 继承的是 Activity , 无法显示ActionBar

已知的必定显示ActionBar的就是 ActionBarActivity

代码:

public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.cool_menu,menu);
        return true;
}



     1.1       全屏加无状态栏:

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//还有一种方法
if(getActionBar()!=null)
    getActionBar.hide(); //getActionBar()可能返回的是null,所以需要检查后再hide



 

2.       OnTouch 方法中,如果return值设为false,系统检测到这个Touch动作做完反应后,就不会再检查这个状态;如果设为true,就会时时检查,于是可以实现拖动的效果。

  补充: 其中还涉及到了父子View的获得OnTouch事件的问题,因此又引出另一个问题——如何只让子View获取OnTouch事件,而父View不会获取?(举个栗子:父View是个ViewPager,而子View也有左右滑动的效果)。答案:

使用requestDisallowInterceptTouchEvent()方法。以下是API文档的说明:

Called when a child does not want this parent and its ancestors to intercept touch events with onInterceptTouchEvent(MotionEvent).

This parent should pass this call onto its parents. This parent must obey this request for the duration of the touch (that is, only clear the flag after this parent has received an up or a cancel.

Parameters
disallowIntercept True if the child does not want the parent to intercept touch events.


 


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);





4.       findViewById() 用于查找和关联控(buttonTextViewImageView 等)

补充:

这个对于老手来说太基础了,但用多了也感觉很麻烦,每次都得写一行代码来关联,如果View比较多,导致代码显得比较冗杂。用于解决这个问题,有个库很受欢迎——ButterKnife: (谁用谁知道~)

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



5.       如果要查找Preference中的控件(如,CheckBoxPreferenceEditTextPreference等)用以下方法:

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




6.       获取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带上附加值Ertra

Intent i = new Intent(CSM_listView.this,ImageViewer.class);
i.putExtra("icon",data.icon);
startActivity(i);
//接收方可以接收查看附加数据
int icon = getIntent().getIntExtra("icon",0);
//也可以分两步,方便查询多个附加数据
Bundle bundle = getIntent().getExtras();
boolean willContinue = bundle.getBoolean("continueGame",false);
int icon = bundle.getInt ("icon",0);




8.       发Intent启动Activity并获取返回值

i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(Intent intent, int requestCode);
//并定义对返回值的处理函数
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK ){ //操作没错误
       Bundle extras = data.getExtras();
       bmp = (Bitmap)extras.get("data");//关键词是“data”
       viewPhoto.setImageBitmap(bmp);
     }
}




9.       播放音乐

MediaPlayer mp;
mp = MediaPlayer.create(this,R.drawable.fengyanghuagu);
mp.setLooping(true);//循环播放
mp.setVolume(0.3f,0.3f);//设置音量
mp.start();
停止播放并释放占用的资源
mp.stop();
mp.release();

 




10.   对话提示框

     10.1 带列表的提示框,点击列表项目启动对应的事件


new AlertDialog.Builder(this).setTitle(R.string.new_game_title)
.setItems(R.array.difficulty, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface, int i) { //i is the position of item clicked
     startGame(i);
}
}).show();
注释:
/**
                    public void onClick(DialogInterface dialog, int which);
         * This method will be invoked when a button in the dialog is clicked.
         *
         * @param dialog The dialog that received the click.
         * @param which The button that was clicked (e.g.
         *            {@link DialogInterface#BUTTON1}) or the position
         *            of the item clicked.
         */
        /* TODO: Change to use BUTTON_POSITIVE after API council */




    10.2 带文本提示和按钮的提示框,点击按钮选择发生的事件


new AlertDialog.Builder(happyNewYear.this).setMessage("想继续游戏吗?").setPositiveButton("继续",new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent i = new Intent(happyNewYear.this,sudugame.class);
                        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        i.putExtra("continueGame",true);
                        startActivity(i);
                        finish();
                    }
                }).setNegativeButton("回主菜单",new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent i = new Intent(happyNewYear.this,sudugame.class);
                        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        i.putExtra("continueGame",false);
                        startActivity(i);
                        finish();
                    }
                }).show();


     10.3  收起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



12.   把较小的数据记录到Preference里方便下次继续,如游戏进度

getPreferences(MODE_PRIVATE).edit()
  .putString(PREF_PUZZLE, toPuzzleString(puzzle))
  .putString("nochange_record",toPuzzleString(nochange_record))
  .commit();

//这里存放了两种记录数据,使用syntax sugar哎呦不错


调用存放的数据

puz = getPreferences(MODE_PRIVATE).getString(PREF_PUZZLE, easyPuzzle[0]);
tempNochange = getPreferences(MODE_PRIVATE).getString("nochange_record",emptyStr);



 


13.   关于StringBuilder

StringBuilder buf = new StringBuilder();   //使用StringBuilder制作string(由于要不停地在结尾添加字符,用这个更方便效率更高)

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


补充:

后来有一次刷算法题的时候,起初用String 的 + 方法进行加长字符串,结果显示运行时间过长,换成了StringBuilder后,立马降低了大幅时间。


 

14.   短时音效的使用(如枪声,按键音)


public SoundPool(int maxStreams, int streamType, int srcQuality)
     * Constructor. Constructs a SoundPool object with the following
     * characteristics:
     *
     * @param maxStreams the maximum number of simultaneous streams for this
     *                   SoundPool object
    * @param streamType the audio stream type as described in AudioManager

     *      For example, game applications will normally use
     *                   {@link AudioManager#STREAM_MUSIC}.
     * @param srcQuality the sample-rate converter quality. Currently has no effect. Use 0 for the default.
     * @return a SoundPool object, or null if creation failed
     * @deprecated use {@link SoundPool.Builder} instead to create and configure a
     *     SoundPool instance
     */


public int load(Context context, int resId, int priority)

  * @param context the application context

     * @param resId the resource ID

     * @param priority the priority of the sound. Currently has no effect. Use

     *                 a value of 1 for future compatibility.

     * @return a sound ID. This value can be used to play or unload the sound.

     */

  


例子:

SoundPool sp;
int explosion = 0;
sp = new SoundPool(5, AudioManager.STREAM_MUSIC,0);
explosion = sp.load(game, R.raw.mie,1);
sp.setVolume(explosion,1,1);
sp.play(explosion,1,1,0,0,1);//播放




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  的常用快捷键

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很方便,如下图:

Android开发学习经验总结——0基础自学(持续更新)Android开发学习经验总结——0基础自学(持续更新)

关了之后,浏览起API简直飞快!

后续:  如果一开始就禁用JavaScript,会导致左侧的导航栏无法滚动,无法查看后面的内容Android开发学习经验总结——0基础自学(持续更新)

因此,建议先保持开启JavaScript,打开了API的某一页(比如packages.html这页),此时左侧导航栏能够正常滚动。然后禁用JavaScript,而所有后续查看的页面都在新的页面打开。


28. 数据持久化——首选项+内部存储+外部存储+数据库

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


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

assets文件夹在android studio中的位置和在Eclipse不一样,位于src\main目录下

Android开发学习经验总结——0基础自学(持续更新)


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,只需要改变第二个参数——


public int getIdentifier (String name, String defType, String defPackage)

Added in   API level 1

Return a resource identifier for the given resource name. A fully qualified resource name is of the form "package:type/entry". The first two components (package and type) are optional if defType and defPackage, respectively, are specified here.

Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.

Parameters
name The name of the desired resource.
defType Optional default resource type to find, if "type/" is not included in the name. Can be null to require an explicit type.
defPackage Optional default package to find, if "package:" is not included in the name. Can be null to require an explicit package.
Returns
  • int The associated resource identifier. Returns 0 if no such resource was found. (0 is not a valid resource ID.)


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



(``````````` 感谢收藏这篇文章的朋友们,出于方便搜索考虑,我决定将一些内容分成多篇文章写,在这里只留链接········································································································)


你可能感兴趣的:(安卓,经验)