android 普及二

android之ListPreference的用法_PreferenceActivity用法

 

首先,我们明确,preference是和数据存储相关的。

       其次,它能帮助我们方便的进行数据存储!为什么这个地方一定要强调下方便的这个词呢?原因是,我们可以根本就不使用,我们有另外的N种办法可以实现同样的功能!它的出现,相当于为我们提供了一个方便的工具,当然了,这个工具并不是必须的。

       preference都应用在什么场景呢?

       这得从android对preference的实现说起,实际上,preference所存储的数据最后都会以xml文件格式的形式进行保存,而且其只能 保存一些基本格式的数据。例如string/boolean……。该xml文件存放的位置在data/data/你应用的包名/shared_prefs 文件夹下。

       种种的限制与实现机制表明了,preference非常适合于参数设置功能。实际上,它也确实是干这个的,我们通过使用preference可以迅速的将某些值保存进xml文件中,然后我们可以读取这些设置信息进行相应的操作。
为了简化与preference相关的应用开发,android为我们提供了一系列的api来帮助我们。主要有PreferenceActivity,ListPreference,EditTextPreference,CheckBoxPreference,RingtonePreference

       下面我们简单的介绍下ListPreference的用法:

我们选择了山东,然后该页面就会自动关闭,并且和山东所对应的值也已经写入了后台的xml文件中。
java代码:

[java] view plain copy

  1. package jason.demo;  
  2.   
  3. import android.os.Bundle;  
  4. import android.preference.ListPreference;  
  5. import android.preference.PreferenceActivity;  
  6. import android.preference.PreferenceManager;  
  7. import android.util.Log;  
  8. /** 
  9. * @description 有关首选项preferences的研究 
  10. * 继承了PreferenceActivity,我们可以方便的对preference进行操作。 
  11. * 例如可以通过getPreferenceManager获取首选项管理器 
  12. * 那,我们可不可以不继承PreferenceActivity呢?当然可以,实际上Activity类中 
  13. * 就有个SharedPreferences getSharedPreferences(String name, int mode)方法呢,我们通过它 
  14. * 也可以对preference进行操作。当然了,如果我们不继承PreferenceActivity的话,那么我们就要手动的 
  15. * 对数据进行保存了。而不是跟现在一样,会自动的根据你的选择项进行数据保存。 
  16. * 那么,preference在这里是怎么样进行自动保存的呢,答案很简单,那就是在addPreferencesFromResource方法的具体实现中! 
  17. */  
  18. public class MyPreferencesActivity extends PreferenceActivity {  
  19. @Override  
  20. public void onCreate(Bundle savedInstanceState) {  
  21. super.onCreate(savedInstanceState);  
  22. addPreferencesFromResource(R.xml.mylistpreference);  
  23. /** 
  24. * getPreferenceManager返回首选项管理器对象 
  25. */  
  26. PreferenceManager manager = getPreferenceManager();  
  27. // 根据android:key中指定的名称(相当于id)来获取首选项  
  28. ListPreference listPreference = (ListPreference) manager.findPreference("myListPreference");  
  29. Log.i("存储的值为"""+listPreference.getValue());  
  30. }  
  31. }  

res/xml/mylistperference.xml布局文件

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!--  
  3. 对于该文件需要注意以下几点  
  4. 第一:位置。该文件的位置是在res/xml/下的。  
  5. 第二:格式,PreferenceScreen为根标签,ListPreference为子标签  
  6. 第三:标签属性含义  
  7. android:key 唯一标识符,和android:id相类似,PreferenceManager可以以其为参数通过findPreference获取指定的preference  
  8. android:title 整个屏幕的标题  
  9. android:summary 选项的简单说明  
  10. android:entries 弹出的对话框中,列表显示的文本内容,注意哦,这里指定的是一个数组  
  11. android:entryValues 与android:entries相对应的值  
  12. android:defaultValue 当对应值不存在时的默认值  
  13. android:dialogTitle 弹出的对话框中的标题信息  
  14. -->  
  15. <PreferenceScreen  
  16. xmlns:android="http://schemas.android.com/apk/res/android"  
  17. android:key="screen_list"  
  18. android:title="标题"  
  19. android:summary="说明摘要"  
  20. >  
  21. <ListPreference  
  22. android:key="myListPreference"  
  23. android:title="标题"  
  24. android:summary="说明摘要"  
  25. android:entries="@array/list_entries"  
  26. android:entryValues="@array/list_entries_value"  
  27. android:dialogTitle="dialogTitle"  
  28. android:defaultValue="@array/list_entries_value2"  
  29. ></ListPreference>  
  30.   
  31. </PreferenceScreen>   

res/values/arrays.xml文件,为上面的文件提供数据

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.  <string-array name="list_entries">  
  4.   <item>山东</item>  
  5.   <item>福建</item>  
  6.   <item>北京</item>  
  7.   <item>河北</item>  
  8.  </string-array>  
  9.  <string-array name="list_entries_value">  
  10.   <item>shandong1</item>  
  11.   <item>fujian1</item>  
  12.   <item>beijing1</item>  
  13.   <item>hebei1</item>  
  14.   </string-array>  
  15.  <string-array name="list_entries_value2">  
  16.   <item>shandong2</item>  
  17.   <item>fujian2</item>  
  18.   <item>beijing2</item>  
  19.   <item>hebei2</item>  
  20.  </string-array>  
  21. </resources>   

当我们运行,并选择了福建时,我们可以查看在shared_prefes下的xml文件如下:

[html] view plain copy

  1. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>  
  2. <map>  
  3. <string name="myListPreference">fujian1</string>  
  4. </map>   

===================================================

android之android.intent.category.DEFAULT的用途和使用

 

1、要弄清楚这个问题,首先需要弄明白什么是implicit(隐藏) intent什么是explicit(明确) intent。

     Explicit Intent明确的指定了要启动的Acitivity ,比如以下Java代码:

[java] view plain copy

  1. Intent intent= new Intent(this, B.class);  

 Implicit Intent没有明确的指定要启动哪个Activity ,而是通过设置一些Intent Filter来让系统去筛选合适的Acitivity去启动。

2、intent到底发给哪个activity,需要进行三个匹配,一个是action,一个是category,一个是data。

理论上来说,如果intent不指定category,那么无论intent filter的内容是什么都应该是匹配的。但是,如果是implicit intent,android默认给加上一个CATEGORY_DEFAULT,这样的话如果intent filter中没有android.intent.category.DEFAULT这个category的话,匹配测试就会失败。所以,如果你的 activity支持接收implicit intent的话就一定要在intent filter中加入android.intent.category.DEFAULT。

例外情况是:

[java] view plain copy

  1. <intent-filter>  
  2.         <action android:name="android.intent.action.MAIN" />  
  3.         <category android:name="android.intent.category.LAUNCHER" />  
  4.     </intent-filter>  


中没有必要加入android.intent.category.DEFAULT,当然加入也没有问题。这个是应用启动默认的第一个启动的activity(每个应用有那么多activity,总得有一个是第一个启动的吧)

 

如果自己定义的某个Activity要通过隐式启动,在AndroidManifast.xm那么必须加上android.intent.category.DEFAULT,否则不起作用

除此之外,category的用途还有很多

比如做个桌面,按home键时启动自己做的应用

[html] view plain copy

  1. <activity  
  2.             android:name=".MainActivity"  
  3.             android:label="@string/app_name" >  
  4.             <intent-filter>  
  5.                 <action android:name="android.intent.action.MAIN" />  
  6.                 <category android:name="android.intent.category.LAUNCHER"/>  
  7.                 <category android:name="android.intent.category.HOME" />  
  8.             </intent-filter>  
  9.         </activity>  

在intent中是如何配置那三个匹配数据的呢,也简单一说

也就是说,在不直接指定要跳转的Activity的时候,为Intent提供一些相关的参数,让其自动去和AndroidManifest.xml中已有的Activity去匹配

IntentFilter在xml中的三個主要的参数:action,categary,data。

我们通过Intent的构造函数或者Intent提供的方法可以指定这个三个参数:    

 

[java] view plain copy

  1. intent.setAction(action);intent.setData(data);intent.addCategory(category);  
  2. intent.setAction(action);  
  3. intent.setData(data);  
  4. intent.addCategory(category);  
  5.  

=======================================================================

 

android之View的启动过程

程序里调用了onSizeChanged方法进行了一些设置,不知道onSizeChanged是在什么时候启动的,所以研究了一下View的启动流程

代码如下:

[java] view plain copy

  1. public class TestView extends View {  
  2.   
  3.     public TestView(Context context) {  
  4.         super(context);  
  5.         Log.d("mDebug""TestView context");  
  6.     }  
  7.   
  8.          public TestView(Context context, AttributeSet attrs) {  
  9.                  super(context, attrs);  
  10.                  Log.d("mDebug""TestView context, attrs="+attrs.getAttributeValue(0));  
  11.          }    
  12.       
  13.     public TestView(Context context, AttributeSet attrs, int defStyle) {  
  14.         super(context, attrs, defStyle);  
  15.         Log.d("mDebug""TestView context,attrs,defStyle attrs="+attrs.getAttributeValue(0));  
  16.     }  
  17.   
  18.   
  19.       
  20.     @Override  
  21.     protected void onDraw(Canvas canvas) {  
  22.         super.onDraw(canvas);  
  23.         Log.d("mDebug""onDraw");  
  24.     }  
  25.   
  26.     @Override  
  27.     protected void onFinishInflate() {  
  28.         super.onFinishInflate();  
  29.         Log.d("mDebug""onFinishInflate");  
  30.     }  
  31.   
  32.   
  33.   
  34.     @Override  
  35.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  36.         super.onSizeChanged(w, h, oldw, oldh);  
  37.         Log.d("mDebug""onSizeChanged,w="+w+",h="+h+",oldw="+oldw+",oldh="+oldh);  
  38.     }  
  39.   
  40. }  

输出如下:

[java] view plain copy

  1. 22:23:03.587: D/mDebug(9715): TestView context, attrs=@2131034112  
  2. 22:23:03.597: D/mDebug(9715): onFinishInflate  
  3. 22:23:03.667: D/mDebug(9715): onSizeChanged,w=720,h=1080,oldw=0,oldh=0  
  4. 22:23:03.727: D/mDebug(9715): onDraw  
  5. 22:23:03.757: D/mDebug(9715): onDraw  


很显然,onSizeChanged的启动时间在onDraw之前

=========================================================================

 

android之ListView的Adapter使用

 

 

在做一个小练习的时候,又遇到了Adapter,才发现以前没有对它进行过记录

现在介绍一下:

其实Adapter就是数据和视图之间的桥梁,数据在adapter中做处理,然后显示到ListView上面

Adapter有很多种,有ArrayAdapter<T>, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter,ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, WrapperListAdapter.

这里就以ArrayAdapter<T>为例来介绍

我自己写的一个例子:

有两个类,一个是主界面Activity,用来处理输入和显示,效果图在最下面,可以翻到最后看一下,布局如下:

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7.     <LinearLayout  
  8.         android:orientation="horizontal"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         >  
  12.         <TextView      
  13.             android:layout_width="wrap_content"   
  14.             android:layout_height="wrap_content"   
  15.             android:text="Name:"  
  16.             />  
  17.         <EditText android:id="@+id/name"  
  18.             android:layout_width="fill_parent"   
  19.             android:layout_height="wrap_content"   
  20.             />  
  21.     </LinearLayout>  
  22.     <LinearLayout  
  23.         android:orientation="horizontal"  
  24.         android:layout_width="fill_parent"  
  25.         android:layout_height="wrap_content"  
  26.         >  
  27.         <TextView      
  28.             android:layout_width="wrap_content"   
  29.             android:layout_height="wrap_content"   
  30.             android:text="Address:"  
  31.             />  
  32.         <EditText android:id="@+id/addr"  
  33.             android:layout_width="fill_parent"   
  34.             android:layout_height="wrap_content"   
  35.             />  
  36.     </LinearLayout>  
  37.     <Button android:id="@+id/save"  
  38.         android:layout_width="fill_parent"  
  39.         android:layout_height="wrap_content"  
  40.         android:text="Save"  
  41.     />  
  42. </LinearLayout>  

java代码如下:

[java] view plain copy

  1. public class LunchList extends Activity {  
  2.     List<Restaurant> model=new ArrayList<Restaurant>();  
  3.     ArrayAdapter<Restaurant> adapter=null;  
  4.       
  5.     @Override  
  6.     public void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.main);  
  9.           
  10.         Button save=(Button)findViewById(R.id.save);  
  11.           
  12.         save.setOnClickListener(onSave);  
  13.           
  14.         ListView list=(ListView)findViewById(R.id.restaurants);  
  15.           
  16.         adapter=new ArrayAdapter<Restaurant>(this,android.R.layout.simple_list_item_1,model);//这行代码在下面解释  
  17.         list.setAdapter(adapter);//为ListView设置我们配置好的适配器  
  18.     }  
  19.       
  20.     private View.OnClickListener onSave=new View.OnClickListener() {  
  21.         public void onClick(View v) {  
  22.             Restaurant r=new Restaurant();  
  23.             EditText name=(EditText)findViewById(R.id.name);  
  24.             EditText address=(EditText)findViewById(R.id.addr);  
  25.               
  26.             r.setName(name.getText().toString());  
  27.             r.setAddress(address.getText().toString());  
  28.               
  29.             RadioGroup types=(RadioGroup)findViewById(R.id.types);  
  30.               
  31.             switch (types.getCheckedRadioButtonId()) {  
  32.                 case R.id.sit_down:  
  33.                     r.setType("sit_down");  
  34.                     break;  
  35.                       
  36.                 case R.id.take_out:  
  37.                     r.setType("take_out");  
  38.                     break;  
  39.                       
  40.                 case R.id.delivery:  
  41.                     r.setType("delivery");  
  42.                     break;  
  43.             }  
  44.               
  45.             adapter.add(r);//每个增加的条目都会添加到适配器里面  
  46.         }  
  47.     };  
  48. }  

针对上面的进行解释:

1. 适配器的作用是数据和视图之间的桥梁

2. 这个小例子是要显示一个数组,我们就用ArrayAdapter,数组适配器,数据的数据类型<>是Restaurant类型的(下面的定义),数据的数据类型还可以是其他的包括对象类型的

3. adapter=new ArrayAdapter<Restaurant>(this, android.R.layout.simple_list_item_1, model);

这段代码是创建一个数组适配器的代码,里面有三个参数,第一个参数是上下文,就是当前的Activity, 第二个参数是android sdk中自己内置的一个布局,它里面只有一个TextView,这个参数是表明我们数组中每一条数据的布局是这个view,就是将每一条数据都显示在这个view上面;第三个参数就是我们要显示的数据,这个数据是以List<Restaurant>的形式存在的,当然我们在设置的时候这个数组里面还没有数据,数据时候来调用adapter.add(r);加入进去的.

listView会根据这三个参数,遍历adapterData里面的每一条数据,读出一条,显示到第二个参数对应的布局中,这样就形成了我们看到的listView. 

 

其实就是两个EditText和一个RadioGroup,用来采集输入的数据,然后存储到下面这个类里面:

[java] view plain copy

  1. package apt.tutorial;  
  2.   
  3. public class Restaurant {  
  4.     private String name="";  
  5.     private String address="";  
  6.     private String type="";  
  7.       
  8.     public String getName() {  
  9.         return(name);  
  10.     }  
  11.       
  12.     public void setName(String name) {  
  13.         this.name=name;  
  14.     }  
  15.       
  16.     public String getAddress() {  
  17.         return(address);  
  18.     }  
  19.       
  20.     public void setAddress(String address) {  
  21.         this.address=address;  
  22.     }  
  23.       
  24.     public String getType() {  
  25.         return(type);  
  26.     }  
  27.       
  28.     public void setType(String type) {  
  29.         this.type=type;  
  30.     }  
  31.       
  32.     public String toString() {  
  33.         return(getName());  
  34.     }  
  35. }  

每增加一个存储,就会在ListView里面显示出来一个
执行之后效果图如下:

 

如果还是不很明白,下面这个网上的代码段更加清晰:

[java] view plain copy

  1. package com.cz.list.demo;   
  2.    
  3. import android.app.Activity;   
  4. import android.os.Bundle;   
  5. import android.widget.ArrayAdapter;   
  6. import android.widget.ListView;   
  7.    
  8. public class ArrayListDemo extends Activity {   
  9.     private ListView listView;   
  10.     private String[] adapterData;   
  11.    
  12.     /** Called when the activity is first created. */   
  13.     @Override   
  14.     public void onCreate(Bundle savedInstanceState) {   
  15.         super.onCreate(savedInstanceState);   
  16.         setContentView(R.layout.array_list_layout);   
  17.    
  18.         /* 找到这个listView */   
  19.         listView = (ListView) findViewById(R.id.array_list);   
  20.    
  21.         /* 我们要在listView上面显示的数据,放到一个数组中 */   
  22.         adapterData = new String[] { "Afghanistan""Albania""Algeria",   
  23.                 "American Samoa""Andorra""Angola""Anguilla",   
  24.                 "Antarctica""Antigua and Barbuda""Argentina""Armenia",   
  25.                 "Aruba""Australia""Austria""Azerbaijan""Bahrain",   
  26.                 "Bangladesh""Barbados""Belarus""Belgium""Belize",   
  27.                 "Benin""Bermuda""Bhutan""Bolivia",   
  28.                 "Bosnia and Herzegovina""Botswana""Bouvet Island" };   
  29.    
  30.         /* 下面就是对适配器进行配置了 */   
  31.         ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>( ArrayListDemo.this, android.R.layout.simple_list_item_1, adapterData);   
  32.    
  33.         /* 设置ListView的Adapter */   
  34.         listView.setAdapter(arrayAdapter);   
  35.     }   

///

 

android之ArrayAdapter的重写

 

 

昨天介绍了ArrayAdapter的使用,今天介绍一下更加实用的一点,对它进行重写,满足自己的个性化设计需要.

ArrayAdapter(数组适配器)一般用于显示一行文本信息,所以比较容易。

[java] view plain copy

  1. public ArrayAdapter(Context context,int textViewResourceId, List<T> objects)  

上面的这行代码来装配数据,要装配这些数据就需要一个连接ListView视图对象和数组数据的适配器来做两者的适配工作,ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局),数据源(一个List集合)。同时用setAdapter()将ListView和Adapter绑定。

例子一:可以用来简单的显示一条文字

[java] view plain copy

  1. package jason.demo14;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.widget.ArrayAdapter;  
  8. import android.widget.ListView;  
  9.   
  10. public class Demo13Activity extends Activity {  
  11.     private ListView lv;  
  12.     private ArrayList<String> list = new ArrayList<String>();  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.         lv = (ListView)findViewById(R.id.listview);  
  18.         ArrayAdapter<String> adapter = new ArrayAdapter<String>(  
  19.                 this,  
  20.                 android.R.layout.simple_expandable_list_item_1,  
  21.                 getData());  
  22.         lv.setAdapter(adapter);  
  23.     }  
  24.       
  25.     private ArrayList<String> getData()  
  26.     {  
  27.         list.add("180平米的房子");  
  28.         list.add("一个勤劳漂亮的老婆");  
  29.         list.add("一辆宝马");  
  30.         list.add("一个强壮且永不生病的身体");  
  31.         list.add("一个喜欢的事业");  
  32.         return list;  
  33.     }  
  34. }  
  35. <span style="font-family:Arial;background-color:#ffffff;"></span>  

 

注意:这里的android.R.layout.simple_expandable_list_item_1是系统内置布局,样式就是如下

 

[java] view plain copy

  1. <span style="font-size:18px;">例子二:这个例子可以增加一个ImageView,但是在设置ArrayAdapter的时候需要增加这个自定义的布局</span>  

[java] view plain copy

  1. public ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects)  

上面的第一个参数是上下文,一般为this。第二个参数是自定义的布局文件,比如下面的就是R.layout.list_item。第三个参数是布局中用来显示文字的TextView的id,第四个参数是数据集合,跟例一一样

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="horizontal" >  
  6.   
  7.     <ImageView   
  8.         android:id="@+id/img"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:src="@drawable/ic_launcher"  
  12.         />  
  13.     <TextView   
  14.         android:id="@+id/tv"  
  15.         android:layout_width="fill_parent"  
  16.         android:layout_height="wrap_content"  
  17.         />  
  18.   
  19. </LinearLayout>  

Activity的java代码:

[java] view plain copy

  1. package jason.demo14;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.widget.ArrayAdapter;  
  8. import android.widget.ListView;  
  9.   
  10. public class Demo13Activity extends Activity {  
  11.     private ListView lv;  
  12.     private ArrayList<String> list = new ArrayList<String>();  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.         lv = (ListView)findViewById(R.id.listview);  
  18.   
  19.         ArrayAdapter<String> adapter = new ArrayAdapter<String>(  
  20.                 this,  
  21.                 R.layout.list_item,//区别就在这一行和下一行,这里是自己定义的布局文件,  
  22.                 R.id.tv,//这是R.layout.list_item中TextView的ID,用来确定把添加进来的数据显示在哪个位置  
  23.                 getData());  
  24.         lv.setAdapter(adapter);  
  25.     }  
  26.       
  27.     private ArrayList<String> getData()  
  28.     {  
  29.         list.add("180平米的房子");  
  30.         list.add("一个勤劳漂亮的老婆");  
  31.         list.add("一辆宝马");  
  32.         list.add("一个强壮且永不生病的身体");  
  33.         list.add("一个喜欢的事业");  
  34.         return list;  
  35.     }  
  36. }  

效果如下:

 

例子3:实现更复杂的效果:

这就需要重写getView方法了,

1. 自定义列表样式

image_item.xml

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
  3.         android:layout_width="fill_parent"   
  4.         android:layout_height="fill_parent"   
  5.         android:orientation="horizontal">   
  6. <ImageView   
  7.     android:id="@+id/item_thumbnail"   
  8.     android:layout_height="48dip"   
  9.     android:layout_width="48dip"   
  10.         />   
  11. <TextView   
  12.     android:id="@+id/item_file_name"   
  13.     android:layout_width="wrap_content"   
  14.     android:layout_height="wrap_content"   
  15.     android:textAppearance="?android:attr/textAppearanceLarge"   
  16.     android:minHeight="?android:attr/listPreferredItemHeight"   
  17.     android:gravity="center_vertical"   
  18.     android:paddingLeft="5dip"   
  19.     />  
  20. </LinearLayout>  


 

2. 自定义ArrayAdapter

[java] view plain copy

  1. public class ImageListAdapter extends ArrayAdapter<File>{   
  2.     private int resource;   
  3.     public ImageListAdapter(Context context, int resourceId, List<File> objects) {   
  4.         super(context, resourceId, objects);   
  5.         // 记录下来稍后使用   
  6.         resource = resourceId;   
  7.     }  
  8.   
  9.     public View getView(int position, View convertView, ViewGroup parent) {   
  10.         LinearLayout imageListView;   
  11.         // 获取数据   
  12.         File file = getItem(position);   
  13.         String fileName = file.getName();   
  14.         Bitmap bitmap = getBitmapFromFile(file);  
  15.   
  16.         // 系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。   
  17.         // 当手动完成适配时,必须手动映射数据,这需要重写getView()方法。   
  18.         // 系统在绘制列表的每一行的时候将调用此方法。   
  19.         // getView()有三个参数,   
  20.         // position表示将显示的是第几行,   
  21.         // covertView是从布局文件中inflate来的布局。   
  22.         // 我们用LayoutInflater的方法将定义好的image_item.xml文件提取成View实例用来显示。   
  23.         // 然后将xml文件中的各个组件实例化(简单的findViewById()方法)。   
  24.         // 这样便可以将数据对应到各个组件上了。   
  25.         //   
  26.         if(convertView == null) {   
  27.             imageListView = new LinearLayout(getContext());   
  28.             LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);   
  29.             inflater.inflate(resource, imageListView, true);//把image_item.xml布局解析到LinearLayout里面   
  30.         } else {   
  31.             imageListView = (LinearLayout)convertView;   
  32.         }  
  33.   
  34.         // 获取控件,填充数据   
  35.         ImageView imageView = (ImageView) imageListView.findViewById(R.id.item_thumbnail);   
  36.         TextView textView = (TextView) imageListView.findViewById(R.id.item_file_name);   
  37.         textView.setText(fileName);   
  38.         imageView.setImageBitmap(bitmap);  
  39.   
  40.         return imageListView;   
  41.     }  
  42.   
  43.     // 从文件获取Bitmap用于填充   
  44.     private Bitmap getBitmapFromFile(File file) {   
  45.         Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());   
  46.         return  bitmap;   
  47.     }   
  48. }  

 

3. 绑定数据

[java] view plain copy

  1. private void bindFilesToList(File[] files) {   
  2.         List<File> fileList = new ArrayList<File>();   
  3.         for(File file : files) {   
  4.             fileList.add(file);   
  5.         }  
  6.   
  7.         ImageListAdapter adapter = new ImageListAdapter(ImageFilesListActivity.this,   
  8.                                                         R.layout.image_item,   
  9.                                                         fileList);   
  10.         setListAdapter(adapter);   
  11. }  

基本就是这样了

 


 

/

对于List的初始化还是有些讲究的.

 

List是一个接口,这个一看文档便知,所以对它初始化不能new List,而应该使用ArrayList或者LinkList(这些实例化了List接口),

[java] view plain copy

  1. List<T> list = new ArrayList<T>();  

而且,如果你确定List里面存放的数据类型,可以直接初始化为这种List,

[java] view plain copy

  1. List<String> list = new LinkedList<String>();  

这样能够快速的处理,存取数据就不用再进行类型转换,直接是String就行了,

如果在初始化时是这样的,

[java] view plain copy

  1. List<Object> list = new LinkedList<Object>();  

那么在存储时就能存储各种类型的数据了,int,String,Map,甚至是你自己定义的class都可以.

当然这样在存取时候是要进行类型转换的,效率会低一些.

 

还有,关于空指针错误真的是很困扰人的一件事情,所以最好的解决方式就是在使用前 一定要保证完成正确的初始化.

///

 

android之通过Button的监听器往adapter中添加数据时出错

本来源代码如下:

[java] view plain copy

  1.     List<Restaurant> model; //自定义的一个List数据,存储的是自定义的类                                      LunchListAdapter adapter;//自定义的一个ListView的适配器  
  2.     ......//省略  
  3. class onSavaLis implements OnClickListener{         //Button save的监听器,点击之后往model里面添加数据  
  4.         Restaurant r = new Restaurant();//②       
  5.         @Override  
  6.         public void onClick(View v) {  
  7.             r.setName(name.getText().toString());  
  8.             r.setAddress(addr.getText().toString());  
  9.             switch (types.getCheckedRadioButtonId()) {  
  10.             case R.id.take_out:  
  11.                 r.setType(TAKE_OUT);  
  12.                 break;  
  13.             case R.id.sit_down:  
  14.                 r.setType(SIT_DOWN);  
  15.                 break;  
  16.             case R.id.delivery:  
  17.                 r.setType(DELIVERY);  
  18.                 break;  
  19.             }  
  20.             model.add(r);//①  
  21.         }  
  22.     }  


问题是,点击存储之后,在如果①处采用的是adapter.add(r);

那么ListView里面展示出来的item全都是最后存进去的那个,而且在点击item之后,从model里面输出来的内容也都是一样的,

如果①处采用的是model.add(r);

那么ListView里面展示出来的item是正确的,刚好是你存储的内容的顺序,但是点击item之后,从model里面读取出来的内容跟上面一样,全都是最后存进去的数据,

 

想来想去也没怎么弄明白,最后我把②那行代码放到了onClick里面定义,这样之后不管①出用哪种方式,显示和输出的结果都是正确的.

暂时想到的就是在②处定义的r可能model里面之前加入的数据都覆盖了,但是还是有点糊涂,先记下这么个印象,望高手赐教.

 

fragment 特点

  • Fragment可以作为Activity界面的一部分组成出现;
  • 可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用;
  • 在Activity运行过程中,可以添加、移除或者替换Fragment;
  • Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响。

//

 

requestWindowFeature可以设置的值有:
 1.DEFAULT_FEATURES:系统默认状态,一般不需要指定

2.FEATURE_CONTEXT_MENU:启用ContextMenu,默认该项已启用,一般无需指定

3.FEATURE_CUSTOM_TITLE:自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时

4.FEATURE_INDETERMINATE_PROGRESS:不确定的进度

5.FEATURE_LEFT_ICON:标题栏左侧的图标

6.FEATURE_NO_TITLE:无标题

7.FEATURE_OPTIONS_PANEL:启用“选项面板”功能,默认已启用。

8.FEATURE_PROGRESS:进度指示器功能

9.FEATURE_RIGHT_ICON:标题栏右侧的图标

 

代码如下

[java] view plain copy

  1. package jason.my;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. import android.os.Handler;  
  5. import android.os.Message;  
  6. import android.view.Window;  
  7. import android.view.WindowManager;  
  8. public class WindowFeatureDemoActivity extends Activity {  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         // requestWindowFeature();的取值  
  13.         // 1.DEFAULT_FEATURES:系统默认状态,一般不需要指定  
  14.         // 2.FEATURE_CONTEXT_MENU:启用ContextMenu,默认该项已启用,一般无需指定  
  15.         // 3.FEATURE_CUSTOM_TITLE:自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时  
  16.         // 4.FEATURE_INDETERMINATE_PROGRESS:不确定的进度  
  17.         // 5.FEATURE_LEFT_ICON:标题栏左侧的图标  
  18.         // 6.FEATURE_NO_TITLE:无标题  
  19.         // 7.FEATURE_OPTIONS_PANEL:启用“选项面板”功能,默认已启用。  
  20.         // 8.FEATURE_PROGRESS:进度指示器功能  
  21.         // 9.FEATURE_RIGHT_ICON:标题栏右侧的图标  
  22.           
  23. //        showFEATURE_INDETERMINATE_PROGRESS();  
  24.         
  25. //        showFEATURE_CUSTOM_TITLE();  
  26.   
  27. //        showFEATURE_LEFT_ICON();  
  28.   
  29. //        showFEATURE_NO_TITLE();     
  30.   
  31.           showFEATURE_PROGRESS();  
  32.     }  
  33.     private void showFEATURE_INDETERMINATE_PROGRESS() {  
  34.         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  
  35.         setContentView(R.layout.main);  
  36.         getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, R.layout.progress);  
  37.         // 必须得加上否则显示不出效果 可以通过这个在以后设置显示或隐藏  
  38.         setProgressBarIndeterminateVisibility(true);  
  39.     }  
  40.     private void showFEATURE_CUSTOM_TITLE() {  
  41.         // 自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时  
  42.          requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  
  43.         setContentView(R.layout.main);  
  44.         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.customtitle);  
  45.     }  
  46.     private void showFEATURE_LEFT_ICON()  
  47.     {  
  48.          requestWindowFeature(Window.FEATURE_LEFT_ICON);  
  49.          setContentView(R.layout.main);  
  50.          getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.icon);  
  51.     }  
  52.     private void showFEATURE_NO_TITLE()  
  53.     {  
  54.          requestWindowFeature(Window.FEATURE_NO_TITLE);  
  55.          setContentView(R.layout.main);  
  56.          // 加上这句设置为全屏 不加则只隐藏title  
  57.          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  58.          WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  59.     }  
  60.     private void showFEATURE_PROGRESS()  
  61.     {  
  62.         requestWindowFeature(Window.FEATURE_PROGRESS);  
  63.         setProgressBarVisibility(true);  
  64.         setContentView(R.layout.main);  
  65.         setTitle("");  
  66.         getWindow().setFeatureInt(Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);  
  67.         // 通过线程来改变ProgressBar的值  
  68.          new Thread(new Runnable() {  
  69.             public void run() {  
  70.                 for (int i = 0; i < 10; i++) {  
  71.                     try {  
  72.                         Thread.sleep(1000);  
  73.                         Message m = new Message();  
  74.                         m.what = (i + 1) * 20;  
  75.                         WindowFeatureDemoActivity.this.myMessageHandler.sendMessage(m);  
  76.                     } catch (Exception e) {  
  77.                         e.printStackTrace();  
  78.                     }  
  79.                 }  
  80.             }  
  81.         }).start();  
  82.     }  
  83.     Handler myMessageHandler = new Handler() {  
  84.         // @Override  
  85.         public void handleMessage(Message msg) {  
  86.             // 设置标题栏中前景的一个进度条进度值  
  87.             setProgress(100 * msg.what);  
  88.             // 设置标题栏中后面的一个进度条进度值  
  89.             setSecondaryProgress(100 * msg.what + 10);  
  90.             super.handleMessage(msg);  
  91.         }  
  92.     };  
  93. }  
  94.  

/

 

android之存储篇_SharedPreferences存储方式

 

SharedPreferences是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data/<包名>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:

  一、根据Context获取SharedPreferences对象

  二、利用edit()方法获取Editor对象。

  三、通过Editor对象存储key-value键值对数据。

  四、通过commit()方法提交数据。

  具体实现代码如下:

 

[java] view plain copy

  1. public class MainActivity extends Activity {  
  2.      @Override  
  3.      public void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.main);  
  6.           
  7.         //获取SharedPreferences对象  
  8.         Context ctx = MainActivity.this;         
  9.         SharedPreferences sp = ctx.getSharedPreferences("SP", MODE_PRIVATE);  
  10.         //存入数据  
  11.         Editor editor = sp.edit();  
  12.         editor.putString("STRING_KEY""string");  
  13.         editor.putInt("INT_KEY"0);  
  14.         editor.putBoolean("BOOLEAN_KEY"true);  
  15.         editor.commit();  
  16.           
  17.         //返回STRING_KEY的值  
  18.         Log.d("SP", sp.getString("STRING_KEY""none"));  
  19.         //如果NOT_EXIST不存在,则返回值为"none"  
  20.         Log.d("SP", sp.getString("NOT_EXIST""none"));  
  21.      }  
  22.  }  

 

   这段代码执行过后,即在/data/data/com.test/shared_prefs目录下生成了一个SP.xml文件,一个应用可以创建多个这样的xml文件。如图所示: 

   SP.xml文件的具体内容如下:

[html] view plain copy

  1. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>  
  2. <map>  
  3. <string name="STRING_KEY">string</string>  
  4. <int name="INT_KEY" value="0" />  
  5. <boolean name="BOOLEAN_KEY" value="true" />  
  6. </map>  

  在程序代码中,通过getXXX方法,可以方便的获得对应Key的Value值,如果key值错误或者此key无对应value值,SharedPreferences提供了一个赋予默认值的机会,以此保证程序的健壮性。如下图运行结果中因为并无值为"NOT_EXIST"的Key,所以Log打印出的是其默认值:“none”。在访问一个不存在key值这个过程中,并无任何异常抛出。  

  SharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。但是SharedPreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。

///

android之存储篇_ContentProvider存储

 ContentProvider是安卓平台中,在不同应用程序之间实现数据共享的一种机制。一个应用程序如果需要让别的程序可以操作自己的数据,即可采用这种机制。并且此种方式忽略了底层的数据存储实现,ContentProvider提供了一种统一的通过Uri实现数据操作的方式。其步骤为:

  1. 在当前应用程序中定义一个ContentProvider。

  2. 在当前应用程序的AndroidManifest.xml中注册此ContentProvider

  3. 其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据。

 

  ContentResolver提供了诸如insert(), delete(), query()和update()之类的方法。用于实现对ContentProvider中数据的存取操作。

  Uri是一个通用资源标志符,将其分为A,B,C,D 4个部分:

    A:无法改变的标准前缀,包括;"content://"、"tel://"等。当前缀是"content://"时,说明通过一个Content Provider控制这些数据  

    B:URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的   类名。例如;"content://com.test.data.myprovider"  

    C:路径,可以近似的理解为需要操作的数据库中表的名字,如:"content://hx.android.text.myprovider/name"中的name

    D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部;

 

  下面通过是代码示例,演示一下如何在应用之间相互获取数据。

  在应用程序A中,继承ContProvider类,并重写其中方法.

[java] view plain copy

  1. public class MyProvider extends ContentProvider{  
  2.     @Override  
  3.     public int delete(Uri uri, String selection, String[] selectionArgs) {  
  4.         // TODO Auto-generated method stub  
  5.         return 0;  
  6.     }  
  7.   
  8.     @Override  
  9.     public String getType(Uri uri) {  
  10.         // TODO Auto-generated method stub  
  11.         return null;  
  12.     }  
  13.   
  14.     @Override  
  15.     public Uri insert(Uri uri, ContentValues values) {  
  16.         return null;  
  17.     }  
  18.   
  19.     //在Create中初始化一个数据库  
  20.     @Override  
  21.     public boolean onCreate() {  
  22.         SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);  
  23.         db.execSQL("create table tab(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");  
  24.         ContentValues values = new ContentValues();  
  25.         values.put("name""test");  
  26.         db.insert("tab""_id", values);  
  27.         db.close();  
  28.         return true;  
  29.     }  
  30.   
  31.     //实现query方法  
  32.     @Override  
  33.     public Cursor query(Uri uri, String[] projection, String selection,  
  34.             String[] selectionArgs, String sortOrder) {  
  35.         SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);  
  36.         Cursor c = db.query("tab"nullnullnullnullnull,null);  
  37.         return c;  
  38.     }  
  39.   
  40.     @Override  
  41.     public int update(Uri uri, ContentValues values, String selection,  
  42.             String[] selectionArgs) {  
  43.         // TODO Auto-generated method stub  
  44.         return 0;  
  45.     }  
  46. }  

在其AndroidManifest.xml中声明此ContentProvider,其中authorities属性定义了此ContentProvider的Uri标识。

[html] view plain copy

  1. <provider android:name=".MyProvider" android:authorities="com.test.MyProvider"/>  


在应用程序B中,通过ContentResolver获取程序A的ContentProvider中的数据。

[java] view plain copy

  1. public class MainActivity extends Activity {  
  2.     @Override  
  3.     public void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.main);  
  6.           
  7.         //获取上下文  
  8.         Context ctx = MainActivity.this;  
  9.         //获取ContentResolver对象  
  10.         ContentResolver resolver = ctx.getContentResolver();  
  11.         //获取Uri对象  
  12.         Uri uri = Uri.parse("content://com.test.MyProvider");  
  13.         //获取数据  
  14.         Cursor c = resolver.query(uri, nullnullnullnull);  
  15.        c.moveToFirst();  
  16.        for(int i=0; i<c.getCount(); i++){  
  17.             int index = c.getColumnIndexOrThrow("name");  
  18.             String src = c.getString(index);  
  19.             Log.d("", src);  
  20.             c.moveToNext();  
  21.        }  
  22.     }  
  23. }  

应用程序B的运行结果如下,从此图可以发现我们在程序B中成功的获取到了程序A中的数据:

再观察两个应用程序的结构,如下图,其中红框是应用程序A的程序结构,可以清楚看到其有一个名为“test_db.db3”的数据库,蓝框是应用程序B的程序结构,其并没有任何数据库用于存储数据。由此图,可以确定应用程序B中查询出来的数据结果是来自于应用程序A。

以上就是ContentProvider的使用方式,这种存储方式相比SQLite和SharedPreferences,其复杂性是显而易见的,但是在处处可见“云”的今天,程序间的数据交互需求令ContentProvider存储机制变成必不可少的一部分。

以上示例代码只是为了展示ContentProvider的使用,所以程序代码中有诸多不合理的地方并未进行处理

///

 

android之activity中onSaveInstanceState和onRestoreInstanceState触发时机

onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。onRestoreInstanceState被调用的前提是,activity A“确实”被系统销毁了

 

android错误之Unable to resolve target 'Google Inc.:Google APIs:6'

修改目录下的project.property文件内容为

target=Google Inc.:Google APIs:16(在这里他本来可能是其他版本号,不用管它,只需要改成你所导入的包的版本就行,

比如我这里已经导入就是api16而他的本来版本是6)

/

 

Android开发中Intent用法总结

Android使用Intent来"封装"程序的"调用意图",不管程序想启动什么组件,启动一个Activity也好,一个service也好,或者一个Broadcast Receiver也好,Android统一使用Intent对象来封装这种"启动意图"。

 

Intent还是应用程序组件之间通信的重要媒介,两个Activity把需要交换的数据封装成Bundle对象,然后使用Intent来携带Bundle对象,这样就实现了两个Activity之间的数据交换。

Intent存在以下几个属性:Component,Action,Category,Data,Type,Extra,Flag七个属性,其中Component属性用来指定需要启动的目标组件,Extra属性用于携带需要交换的数据

下面对Intent对象做详细的介绍:

1. Intent的Component属性

Component是用来指定启动目标组件的属性,标准的启动代码如下:

?

1

2

3

4

ComponentName comp = new ComponentName(firstActivity.this,secondActivity.class);

Intent intent = new Intent();

Intent. setComponent(comp);

startActivity(intent);

以上代码用来标准的创建ComponentName对象,进而调用Intent对象的setComponent()函数来为Intent设定相应的componentName,最后调用startAcitvity函数启动一个新的Activity。

实际上,当需要为Intent设定Component属性的时候,Intent已经为我们提供了一个简单的构造器,使用方法如下(我们经常使用的方式):

复制代码代码如下:

Intent intent = new Intent(firstActivity.this,senondActivity.class);


值得一提的是,在secondActivity组件中,可以使用getIntent()方法取得调用次组件的Intent对象,进而,getXXX方法在这里就可以各种使用了。

 

2. Intent 的Action与Category属性

Action和Category属性都是普通的字符串,其中Action代表了抽象出来的"动作",Category属性用来和Action属性配合使用,表达出要启动某组件的意图。

具有<intent-filter…/>标签的Activity均有可能会被启动。

比如:

?

1

2

3

4

5

6

Public final staticString SOME_ACTION = "org.someaction.SOME_ACTION"

// 这是一个字符转,随便设定,但是一般都具有一些抽象的语义。

在这个Activity种的某个按钮的onClick()方法中加入:

Intent intent = newIntent();

Intent.setAction(thisActivity.SOME_ACTION);

startActivity(intent);

这样的代码并没有具体指出要启动哪个Activity,这样就脱离了"硬编码",但是具体要启动哪个Activity呢,这将取决于Activity配置文件中的<intent-filter…/>标签。

<intent-filter…/>是AndroidManifest.xml文件中<activity…/>元素的子元素,需要做的,就是给你实际需要相应这个意图的Activity添加<intent-filter…/>标签,在<intent-filter…/>下,存在着三种标签:1.<action…/>2.<category…/>3.<data…/>,其中指定android:name属性之后,这个activity便具有了相应上面意图的属性了。

对于上面的意图,则添加这样的代码(当然要在<intent-filter…/>标签下):

复制代码代码如下:

<action android:name = "org.someaction.SOME_ACTION"/>


需要一提的是:一个activity对象最多只能包含一个action属性,程序调用setAction(Stringstr)来设定Action的属性值;而一个Activity可以有多个Category属性,程序可以调用addCategory(String str)来添加Category属性。当程序创建Intent的时候,创建的Intent属性自动启动属性值为Intent.CATEGORY_DEFAULT常量,其值为"android.intent.category.DEFAULT",所以,在配置某个Activity属性的时候<categoryandroid:name = "andrid.intent.category.DEFAULT ">是可以添加到配置文件当中的。

 

实际上Android内部提供了大量的标准的Action和Category常量。

总结如下:

 

Action常量

对应的android:name 设定

简单说明

ACTION_MAIN

Android.intent.action.MAIN

应用程序入口

ACTION_VIEW

Android.intent.action.VIEW

显示指定数据

ACTION_ATTACH_DATA

Android.intent.action.ATTACH_DATA

指定某模块数据被附加的地方

ACTION_EDIT

Android.intent.action.EDIT

编辑指定数据

ACTION_PICK

Android.intent.action.PICK

从列表中选择某项并返回所选数据

ACTION_CHOOSER

Android.intent.action.CHOOSER

显示一个Activity选择器

ACTION_GET_CONTENT

Android.intent.action.GET_CONTENT

让用户选择数据,并返回所选

ACTION_DIAL

Android.intent.action.DIAL

显示拨号面板

ACTION_SEND

Android.intent.action.SEND

直接发送数据

ACTION_SENDTO

Android.intent.action.SENDTO

直接发送消息

ACTION_ANSWER

Android.intent.action.ANSWER

应答电话

ACTION_INSERT

Android.intent.action.INSERT

插入数据

ACTION_DELETE

Android.intent.action.DELETE

删除数据

ACTION_RUN

Android.intent.action.RUN

运行数据

ACTION_SYNC

Android.intent.action.SYNC

执行数据同步

ACTION_PICK_ACTIVITY

Android.intent.action.PICK_ACTIVITY

用于选择activity

ACTION_SEARCH

Android.intent.action.SEARCH

执行搜索

ACTION_WEB_SEARCH

Android.intent.action. WEB_SEARCH

直径web搜索

ACTION_ FACTORY_TEST

Android.intent.action.FACTORY_TEST

工厂测试入口点

 

这里仅仅摘录一些,如果想了解全部的ACTION,可以直接查看Android的标准API中有关Intent的说明部分。

3. Intent中的Data和Type属性

采用几个例子来说明Data的用法:

在一个button的OnClick()方法中添加下面代码:

?

1

2

3

4

5

String data = http://3g.renren.com;

Uri uri =Uri.parse(data);

Intent.setAction(Intent.ACTION_VIEW);

Intent.setData(uri);

startActivity(intent);

此方法中将会使得按钮启动人人网。

当然一下代码是简便的写法:

?

1

2

3

Uri myUri = Uri.parse("http://3g.renren.com");

Intent intent = new Intent(Intent.ACTION_VIEW,myUri);

startActivity(intent);

上面的为其更详细的设定方法。

4. Intent的Extra属性

Intent属性通常用来用于在多个Activity之间进行数据交换,Intent的Extra属性值应该是一个Bundle对象,他可以输入多个key-value对,这样就可以通过Intent在不同的Activity之间进行相应的数据交换了。

Intent提供的方法有如下几个:

putExtra(Bundledata)   getExtras()
putXXX(Stringkey XXX data)   getXXX(String key)
putSerializable(Stringkey, Serializable data) 对应的有
getSerializable(Stringkey, Serializable data)

在课件中已经给出了添加键值对的相关代码,这里就不在重复了。

总结:

Android应用总是要借助Intent来实现需要启动的某个组件,Intent就是这种"启动意图"的封装形式,这种意图并没有和任何程序组件耦合,通过这种方式即可以很好的提供了程序的可扩展性和可维护性,其中<intent-filter/>的配置是程序组件最为重要的标签

android之知识点小结一

Manifest.xml文件中的一些代码作用:

[html] view plain copy

  1. <activity android:name=".LunchList"  
  2.           android:label="@string/app_name">  
  3.         <intent-filter>  
  4.                 <action android:name="android.intent.action.MAIN" />  
  5.                 <category android:name="android.intent.category.LAUNCHER" />  
  6.         </intent-filter>  
  7.         <intent-filter>  
  8.                 <action android:name="android.intent.action.SEARCH" />  
  9.                 <category android:name="android.intent.category.DEFAULT" />  
  10.         </intent-filter>  
  11.         <meta-data android:name="android.app.searchable"  
  12.                    android:resource="@xml/searchable" />  
  13.         <meta-data android:name="android.app.default_searchable"  
  14.                    android:value=".LunchList" />  
  15. </activity>  

在上面这段代码中,

[html] view plain copy

  1. <intent-filter>  
  2.         <action android:name="android.intent.action.SEARCH" />  
  3.         <category android:name="android.intent.category.DEFAULT" />  
  4.       </intent-filter>  

这个是注册的隐式Intent的过滤器,第二行表示过滤带有搜索action的intent,第三行是必须要添加的(自定义的Activity如果要通过隐式intent启动,则必须添加)

 

[html] view plain copy

  1. <meta-data android:name="android.app.searchable"  
  2.       android:resource="@xml/searchable" />  

这个是在使用默认的搜索框架是,给搜索框设置的布局,第一行name是给定的,第二行resource就是你给自己的搜索框设置的外观布局,一般放在res/xml里

 

[html] view plain copy

  1. <meta-data android:name="android.app.default_searchable"  
  2.            android:value=".LunchList" />  

这个也是和搜索相关,上面两个是通过intent_filter过滤接收到intent,以及接收到intent之后显示出来的搜索框的布局,但那样只是在你注册了meta-data节点的activity里面才能执行搜索,如果想要在任意一个activity里面都能启动搜索框架,就要加上这个,这个第一行也是给定的,第二行则用来指定是由哪一个activity响应并执行搜索和显示搜索结果.

 

[html] view plain copy

  1. <receiver android:name=".AppWidget"  
  2.         android:label="@string/app_name"  
  3.         android:icon="@drawable/icon">  
  4.         <intent-filter>  
  5.                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>  
  6.                 <category android:name="android.intent.category.DEFAULT" />  
  7.         </intent-filter>  
  8.         <meta-data  
  9.                 android:name="android.appwidget.provider"  
  10.                 android:resource="@xml/widget_provider" />  
  11. </receiver>  

这段代码中:注册的是一个Widget,其中第二行是widget的标题,第三行是它的图标,

 

[html] view plain copy

  1. <intent-filter>  
  2.         <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>  
  3.         <category android:name="android.intent.category.DEFAULT" />  
  4. </intent-filter>  

这个跟最上面的类似,就是注册了intent的过滤器,过滤widget的更新action,第三行在上面解释过了,这里的更新actiong是放在隐式intent里面的,所以要加上第三行

 

[html] view plain copy

  1. <meta-data  
  2.     android:name="android.appwidget.provider"  
  3.     android:resource="@xml/widget_provider" />  

这个则是对widget的参数配置,第二行是指定的,第三行就是我们自定义的widget参数,放在res/xml下,这里的配置如下:res/xml/widget_provider.xml

[html] view plain copy

  1. <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"  
  2.      android:minWidth="300dip"  
  3.      android:minHeight="79dip"  
  4.      android:updatePeriodMillis="1800000"  
  5.      android:initialLayout="@layout/widget"  
  6. />  

二三四行分别是宽高和更新频率,第五行则是该widget的具体布局,布局方式与layout里的其他布局方式一样:res/layout/widget.xml

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="@drawable/widget_frame"  
  6. >  
  7.     <TextView android:id="@+id/name"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:layout_centerVertical="true"  
  11.         android:layout_alignParentLeft="true"  
  12.         android:layout_toLeftOf="@+id/next"  
  13.         android:textSize="10pt"  
  14.         android:textColor="#FFFFFFFF"  
  15.     />  
  16.     <ImageButton android:id="@+id/next"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_height="wrap_content"  
  19.         android:layout_centerVertical="true"  
  20.         android:layout_alignParentRight="true"  
  21.         android:src="@drawable/ff"  
  22.     />  
  23. </RelativeLayout>  

///

 

android之知识点小结二

SharedPreferences的使用:

在这里也是偏向于使用android自带的SharedPreferences管理机制,简要说明使用流程,备忘:

首先在主activity里面初始化SharedPreferences,

[java] view plain copy

  1. SharedPreferences prefs=null;  
  2. ...  
  3. @Override  
  4.  public void onCreate(Bundle savedInstanceState) {  
  5. ...  
  6. prefs=PreferenceManager.getDefaultSharedPreferences(this);  
  7. ...  
  8. /*注册SharedPreferences的监听器,一旦SharedPreferences发生变化,则触发监听器,进行一些操作,比如这里是通过SharedPreferences设置列表的排序方式,一旦排序方式的设置改变,则*SharedPreferences的存储内容改变,则触发监听器,进行列表的重新初始化 
  9. */  
  10. prefs.registerOnSharedPreferenceChangeListener(prefListener);  
  11. ...  
  12. }  
  13. .  
  14. .  
  15. .  
  16. private SharedPreferences.OnSharedPreferenceChangeListener prefListener=  
  17.   new SharedPreferences.OnSharedPreferenceChangeListener() {  
  18.   public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) {  
  19.    if (key.equals("sort_order")) {//这里就是监听器的具体操作,通过判断是某一个SharedPreferences的变化,进行相应操作  
  20.     initList();//重新初始化列表  
  21.    }  
  22.   }  
  23.  };.  
  24. .  
  25. private void initList() {  
  26. ...  
  27. model=helper.getAll(where, prefs.getString("sort_order""name"));  
  28. //在这里需要通过prefs.getString("sort_order", "name")获取SharedPreferences中存取的具体内容,即采取何种排列方式,如果结果为空,则返回"name",按姓名排序  
  29. ...  
  30. }  

上面则完成了对SharedPreferences的一系列操作,从初始化和注册监听器,监听变化,以及变化后做出相应操作,

那么是如何唤出SharedPreferences的设置界面,并且存储是如何实现的呢,
这里采用的是

[java] view plain copy

  1. if (item.getItemId()==R.id.prefs) {  
  2.  startActivity(new Intent(this, EditPreferences.class));  
  3. }  

就是在菜单里加一个prefs设置选项,点击它则启动定义的SharedPreferences设置界面,这个界面就直接继承PreferenceActivity,可以方便高效的实现Preference的存储和管理.代码如下:

[java] view plain copy

  1. public class EditPreferences extends PreferenceActivity {  
  2.     @Override  
  3.     public void onCreate(Bundle savedInstanceState) {  
  4.         super.onCreate(savedInstanceState);  
  5.         addPreferencesFromResource(R.xml.preferences);//这个方法的实现就内置了SharedPreferences的存储方法,所以无需我们自己再去存储SharedPreferences  
  6.     }  
  7. }  

代码是很简单的,只需要addPreferencesFromResource(R.xml.preferences);这个设置显示界面就可以了,

界面代码res/xml/preferences.xml:

[html] view plain copy

  1. <PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android">  
  2.     <ListPreference  
  3.         android:key="sort_order"  
  4.         android:title="Sort Order"  
  5.         android:summary="Choose the order the list uses"  
  6.         android:entries="@array/sort_names"  
  7.         android:entryValues="@array/sort_clauses"  
  8.         android:dialogTitle="Choose a sort order" />  
  9. </PreferenceScreen>  

整个界面是一个PreferenceScreen,第二行,是一个ListPreference,key就相当于id,也是键值对的key,实际存储之后就是一个键值对的键,在前面的initList里面

[java] view plain copy

  1. model=helper.getAll(where, prefs.getString("sort_order""name"));  

我们就是用prefs.getString("sort_order","name");去获取内容的,很明显这里用到的就是key,

title就是ListPreference的标题,summary是简单说明用法,效果如下,显示位置很明显就体会到其用途了.

再有就是所显示的具体内容了,ListPreference里的选项是从哪里来的呢,来自

android:entries="@array/sort_names"

这个数组定义了要显示的内容,而下一行

android:entryValues="@array/sort_clauses"

这行定义了对应着你所选的选项,存储到SharedPreferences里面的内容,整个数组的资源代码如下

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string-array name="sort_names">  
  4.         <item>By Name, Ascending</item>  
  5.         <item>By Name, Descending</item>  
  6.         <item>By Type</item>  
  7.         <item>By Address, Ascending</item>  
  8.         <item>By Address, Descending</item>  
  9.     </string-array>  
  10.     <string-array name="sort_clauses">  
  11.         <item>name ASC</item>  
  12.         <item>name DESC</item>  
  13.         <item>type, name ASC</item>  
  14.         <item>address ASC</item>  
  15.         <item>address DESC</item>  
  16.     </string-array>  
  17. </resources>  

比如我们在选择时,选择了第一个By Name, Ascending,那么系统自动帮你把name ASC存储到SharedPreferences里面,即

所存储的这条SharedPreferences为(SharedPreferences的存储方式就是xml文件的形式存储)

<string name="sort_order">name ASC</string>

那么在看前面的这行代码

[java] view plain copy

  1. model=helper.getAll(where, prefs.getString("sort_order""name"));  

很明显,这个prefs所获取到的内容就是"name ASC",这行代码其实就是把参数传递到数据库帮助类里用来获取内容,而这个获取到的SharedPreferences就是设置的排序方式

//

android之存储篇_存储方式总览

作为一个完成的应用程序,数据存储操作是必不可少的。因此,Android系统一共提供了四种数据存储方式。分别是:SharePreference、SQLite、Content Provider和File。由于Android系统中,数据基本都是私有的的,都是存放于“data/data/程序包名”目录下,所以要实现数据共享,正确方式是使用Content Provider。

  SQLite: SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据存储方式。Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。

  SharedPreference: 除SQLite数据库外,另一种常用的数据存储方式,其本质就是一个xml文件,常用于存储较简单的参数设置。

  File: 即常说的文件(I/O)存储方法,常用语存储大数量的数据,但是缺点是更新数据将是一件困难的事情。

  ContentProvider: Android系统中能实现所有应用程序共享的一种数据存储方式,由于数据通常在各应用间的是互相私密的,所以此存储方式较少使用,但是其又是必不可少的一种存储方式。例如音频,视频,图片和通讯录,一般都可以采用此种方式进行存储。每个Content Provider都会对外提供一个公共的URI(包装成Uri对象),如果应用程序有数据需要共享时,就需要使用Content Provider为这些数据定义一个URI,然后其他的应用程序就通过Content Provider传入这个URI来对数据进行操作。

PS: URI由3个部分组成:"content://"、数据的路径、标识ID(可选)。

//

 

android之IntentFilter的用法android.intent.action.TIME_TICK在manifest.xml不起作用

在模仿一个天气预报的widget时候,用到了IntentFilter,感觉在manifest.xml注册的receiver跟用代码写registerReceiver()的效果应该是相同的,于是想证明一下,就写了如下一段程序:

MainActivity:

public class MainActivity extends AppCompatActivity {
/*
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
*/
public static final int UPDATE = 000;
    TextView xml;
    TextView java;
    int count = 0;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            switch (msg.what) {
                case UPDATE:
                    count ++;
                    xml.setText(count);
                    break;


                default:
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        IntentFilter javaFilter = new IntentFilter();
        javaFilter.addAction("android.intent.action.TIME_TICK");
        registerReceiver(receiver, javaFilter);
        xml = (TextView) findViewById(R.id.xml);
        java = (TextView) findViewById(R.id.java);
    }


    BroadcastReceiver receiver = new BroadcastReceiver() {


        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("HHmm");
            java.setText(dateFormat.format(date));
        }
    };


    protected void onDestroy() {
        unregisterReceiver(receiver);
    };


    class Accept extends BroadcastReceiver {


        @Override
        public void onReceive(Context arg0, Intent arg1) {
            // TODO Auto-generated method stub
            Message message = handler.obtainMessage();
            message.what = UPDATE;
            handler.sendMessage(message);
        }


    }

}

在manifest文件中注册如下:

      <receiver android:name="com.example.android.test.MainActivity.Accept">
            <intent-filter >
                <action android:name="android.intent.action.TIME_TICK"/>
            </intent-filter>

        </receiver>

布局文件如下:

 

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical">  
  6.   
  7.     <TextView  
  8.         android:id="@+id/xml"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="@string/hello_world" />  
  12.   
  13.     <TextView  
  14.         android:id="@+id/java"  
  15.         android:layout_width="wrap_content"  
  16.         android:layout_height="wrap_content"  
  17.         android:text="@string/hello_world" />  
  18.   
  19. </LinearLayout>  

/

 

Android属性之build.prop生成过程

本文简要分析一下build.prop是如何生成的。Android的build.prop文件是在Android编译时刻收集的各种property(LCD density/语言/编译时间, etc.),编译完成之后,文件生成在out/target/product/<board>/system/目录下。在Android运行时刻可以通过property_get()[c/c++域] / SystemProperties_get*()[Java域]读取这些属性值。

 

build.prop的生成是由make系统解析build/core/Makefile完成。

1)      Makefile中首先定义各种变量,这在下一步执行时会用到。比如:

 

[plain] view plain copy

  1. ...  
  2. PRODUCT_DEFAULT_LANGUAGE="$(calldefault-locale-language,$(PRODUCT_LOCALES))" \  
  3. PRODUCT_DEFAULT_REGION="$(calldefault-locale-region,$(PRODUCT_LOCALES))" \  
  4. ...  

2)      Makefile中调用build/tools/buildinfo.sh执行脚本,并输出到build.prop

Buildinfo.sh很简单,只是echo一些属性,比如:

 

[plain] view plain copy

  1. ...  
  2. echo"ro.product.locale.language=$PRODUCT_DEFAULT_LANGUAGE"  
  3. echo"ro.product.locale.region=$PRODUCT_DEFAULT_REGION"  
  4. ...  

而,ro.product.locale.language/ ro.product.locale.region就是些属性,等号后面是值。

3)      Makefile中直接把$(TARGET_DEVICE_DIR)/system.prop的内容追加到build.prop中。

4)      收集ADDITIONAL_BUILD_PROPERTIES中的属性,追加到build.prop中。

ADDITIONAL_BUILD_PROPERTIES又会收集PRODUCT_PROPERTY_OVERRIDES中定义的属性

 

[plain] view plain copy

  1. ADDITIONAL_BUILD_PROPERTIES:= \  
  2.         $(ADDITIONAL_BUILD_PROPERTIES)\  
  3.         $(PRODUCT_PROPERTY_OVERRIDES)  

 

通过build.prop生成过程的分析,可知哪里可以修改原有的属性或加入自己定义属性,那就是2) buildinfo.sh; 3) system.prop; 4) ADDITIONAL_BUILD_PROPERTIES或PRODUCT_PROPERTY_OVERRIDES。不过个人建议改在system.prop或PRODUCT_PROPERTY_OVERRIDES,这对应于具体特定平台或产品的修改。

/

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值