Android 布局组件
•View(android原生UI父类对象,它分为基本view,容器view)
•ViewGroup(view容器,布局基本view组件)
Android UI中的ViewGroup
1.Common Layout
1.RelativeLayout (相对布局)
2.LinearLayout (线性布局)
3.GridLayout (网格布局)
4.FrameLayout(帧布局)
5)……
2.Adapter Layout
1.ListView (列表视图)
2.GridView(网格视图)
3.Spinner(下拉列表)
4.ViewPager(视图分页)
Common Layout 优化
1.优化继承体系(减少层次结构)
例如:借助merge标签实现相同布局的合并
<merge xmlns:android="http://schemas.android.com/apk/res/android">
</merge>
2.重用layout对象
例如:借助include标签导入共用布局
<include layout="@layout/top_title_layout_1"/>
3.实现对象的延迟加载(借助ViewStub)
<!-- 借助此标签实现元素的延迟加载 -->
<ViewStub
android:id="@+id/stub_id"
android:inflatedId="@+id/tv01"
android:layout="@layout/layout_tv_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Adapter layout
所有的Adapter Layout都直接或间接的继承了ViewGroup,并借助一个Adapter对象加载数据,构建item对象,然后以某种方式呈现给用户。
常用的Adapter Layout如下:
1.ListView (以列表形式显示数据)
2.GridView ( 以网格形式显示数据)
3.Spinner (以下拉列表的形式显示数据)
4.ViewPager(以分页形式显示数据)
ListView 的简单应用
1.ListView 应用实现的基本步骤
1.构建ListView对象
2.准备item view,item数据
3.构建Adapter,组装数据,构建item.
4.Listview 关联adapter.
常见Adapter (构建adapter layout需要的item)
1.ArrayAdapter (数据集比较简单,可以是数组或list集合)
2.SimpleAdapter (数据集为List<? extends Map>)
3.BaseAdapter(抽象类):自己写adapter可继承此类
4.SimpleCursorAdapter(数据集为一个Cursor对象)
ArrayAdapter
示例:
public class MainActivity extends Activity implements OnItemClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.构建或获得ListView对象
ListView lsv=(ListView)findViewById(R.id.lsvId);
//2)item data
String data[]={"关羽","张飞","赵云","黄忠","马超"};
//3.构建Adapter对象
//参数:context item(布局) 布局中要显示元素的view data(数组)
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, R.layout.list_item_res_2,R.id.tv02, data);
//3.listview 关联adapter
lsv.setAdapter(adapter);
//4.添加监听器 item点击事件
lsv.setOnItemClickListener(this);
}
/**当点击listview中的某个item时会自动执行此方法*/
//参数 parent =item view=点击的元素 pos=item在listview中的位置
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
TextView tv=(TextView)
view.findViewById(R.id.tv02);
Toast.makeText(this,tv.getText(), 1).show();
}
}
SimpleAdapter
示例:
public class MainActivity extends Activity {
2. private List<Map<String,Object>> data=
3. new ArrayList<Map<String,Object>>();
4. @Override
5. protected void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.activity_main);
8. initData();
9. //1.获得listview
10. ListView lsv=(ListView) findViewById(R.id.lsvId);
11. //2.创建adapter
12. //SimpleAdapter 一次可以传递多个值
13. SimpleAdapter adapter=new SimpleAdapter(this,//context
14. data, //List<? extends Map<String,?>>:list集合 集合里存储的是map对象
15. R.layout.list_item_3, //item layout
16. new String[]{"imgKey","titleKey","dateKey"},//map中的key
17. new int[]{R.id.imgId,R.id.tvId02,R.id.tvId01});//item layout 中的位置
18. //3.关联adapter
19. lsv.setAdapter(adapter);
20. }
21. int imgs[]={R.drawable.png_01,R.drawable.png_02,R.drawable.png_03,R.drawable.png_04,R.drawable.png_05};
22.
23. /**初始化数据*/
24. private void initData(){
25. for(int i=0;i<5;i++){
26. Map<String,Object> map=
27. new HashMap<String, Object>();
28. map.put("imgKey", imgs[i]);
29. map.put("titleKey", "title"+i);
30. map.put("dateKey", "2016-04-05");
31. data.add(map);
32. }
33. }
34.}
自定义Adapter 继承BaseAdapter
示例:
public class MainActivity extends Activity implements OnItemClickListener {
2. private List<News> list=new ArrayList<News>();
3. @Override
4. protected void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.activity_main);
7. initData();
8. //1.获得ListView
9. ListView lsv=(ListView) findViewById(R.id.lsvId);
10. //2.构建自定义 adapter对象
11. NewsAdapter adapter=new NewsAdapter(this, R.layout.news_item_3, list);
12. //3.关联adapter
13. lsv.setAdapter(adapter);
14. //4.添加监听器
15. lsv.setOnItemClickListener(this);
16. }
17. //初始化数据 获取SD卡目录下所有的png图片
18. private void initData(){
19. File sdcard= new File("/mnt/sdcard/Pictures");
20. //获取列表 并添加筛选器
21. File imgs[]=sdcard.listFiles(new FileFilter() {
22. @Override
23. public boolean accept(File file) {
24. // 如果不是文件夹并且以png结尾
25. return file.isFile()&&file.getName().endsWith(".png");
26. }
27. });
28. //将图片封装成新闻对象 当做新闻的logo
29. for(int i=0;i<imgs.length;i++){
30. News n=new News();
31. n.setTitle("新闻-"+i);
32. n.setContent("新闻内容-"+i);
33. n.setLogo(imgs[i].getPath());
34. n.setBirthday("2016-04-06");
35. list.add(n);
36. }
37.
38. }
39. //ListView item 点击事件 点击新闻弹出新闻内容
40. @Override
41. public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
42. Object obj=parent.getItemAtPosition(position);
43. if(obj instanceof News){
44. News n=(News)obj;
45. Toast.makeText(this,n.getContent(), 0).show();
46. }
47. }
48.}
adapter代码:
示例:
/**自定义适配器 继承BaseAdapter */
2.public class NewsAdapter extends BaseAdapter{
3. private Context context;
4. private int resource;
5. private List<News> list;
6. //仿照arrayAdapter的构造方法 需要context 布局 数据源
7. public NewsAdapter(Context context,int resource,List<News> list) {
8. this.context=context;
9. this.resource=resource;
10. this.list=list;
11. }
12. /**用于返回数据集中数据的个数*/
13. @Override
14. public int getCount() {
15. return list.size();
16. }
17. /**一般返回为当前位置的item对应的数据*/
18. @Override
19. public Object getItem(int position) {
20. return list.get(position);//News
21. }
22. @Override
23. public long getItemId(int position) {
24. return position;
25. }
26. /**构建adapter layout要显示的item(包饺子)
27. * 每显示一个item都会调用一次此方法*/
28. //每个item都是一个view
29. @Override
30. public View getView(int position, View convertView, ViewGroup parent) {
31. //1.item layout对象(准备饺子皮对象)
32. //1)借助context找到resource id对应的xml资源
33. //2)借助xmlpullparser解析xml资源
34. //3)借助反射构建xml元素对象
35. //4)inflate方法的返回值为resource资源对应的根元素对象
36. View v=View.inflate(context,resource,null);
37. //2.item data 准备数据
38. News news=list.get(position);
39. //3.set item data to item layout
40. ImageView img=(ImageView) v.findViewById(R.id.logo);
41. TextView titleTv=(TextView) v.findViewById(R.id.titleId);
42. TextView dateTv=(TextView) v.findViewById(R.id.dateId);
43. img.setImageURI(Uri.fromFile(new File(news.getLogo())));
44. titleTv.setText(news.getTitle());
45. dateTv.setText(news.getBirthday());
46. return v;//包好的饺子
47. }
48.}
adapter的优化
示例:
//adapter的优化 保证列表项item对象够一屏用,避免产生太多对象
2. @Override
3. public View getView(int position, View convertView, ViewGroup parent) {
4. Log.i("TAG", ""+convertView);
5. View v = null;
6. ViewHolder vh = null;
7. if (convertView == null) {// convertView (可重用的列表项对象)
8. v = View.inflate(context, resource, null);
9. vh = new ViewHolder();
10. vh.logo = (ImageView) v.findViewById(R.id.logo);
11. vh.titleTv = (TextView) v.findViewById(R.id.titleId);
12. vh.dateTv = (TextView) v.findViewById(R.id.dateId);
13. v.setTag(vh);// 关联viewholder
14. } else {
15. v = convertView;
16. vh = (ViewHolder) convertView.getTag();
17. }
18. // 2.item data (饺子馅)
19. News news = list.get(position);
20. // 3.set item data to item layout(将饺子馅放到饺子皮上包起来)
21. vh.logo.setImageURI(Uri.fromFile(new File(news.getLogo())));
22. vh.titleTv.setText(news.getTitle());
23. vh.dateTv.setText(news.getBirthday());
24. return v;// 包好的饺子
25. }
26. /**每个item view对应一个viewHolder*/
27. class ViewHolder{
28. ImageView logo;
29. TextView titleTv;
30. TextView dateTv;
31. }
ListView中元素的点击实现
Activity可以直接继承ListActivity 那样就不需要自己再写布局文件了,这样就内置了一个ListView可以直接使用。
需要做以下两点之一:
1:注释onCreat中的这句话://setContentView(R.layout.activity_main);
2.或者在main_activity中写一个ListView 但是ID必须是: android:id=”@id/android:list”
如果需要让item中的button可点击必须在布局文件中加上这句话: android:descendantFocusability=”blocksDescendants”
示例:
public class MainActivity extends ListActivity {
2. List<String> list=new ArrayList<String>();
3. @Override
4. protected void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. //setContentView(R.layout.activity_main);
7. list.add("A");list.add("B");list.add("C");
8. //调用listactivity中的方法
9. Log.i("TAG","activity.onCreate");
10. setListAdapter(
11. new ArrayAdapter<String>(this,R.layout.list_item_2,R.id.textView1,list){
12. //重写adapter的getView 方法 获取item中的Button
13. @Override
14. public View getView(int position, View convertView, ViewGroup parent) {
15. View v=super.getView(position, convertView, parent);
16. final ImageView btn=(ImageView)
17. v.findViewById(R.id.button1);
18. btn.setTag(position);
19. //给button 添加点击事件
20. btn.setOnClickListener(new OnClickListener() {
21. @Override
22. public void onClick(View v) {
23. //删除集合中数据
24. list.remove(((Integer)btn.getTag()).intValue());
25. //调用adapter的方法通知listview更新
26. notifyDataSetChanged();
27. }
28. });
29. return v;
30. }
31. });
32.
33. }
34.}
ListView 实现选择 排序
示例:
public class MainActivity extends ListActivity {
2. List<String> list=new ArrayList<String>();
3. ArrayAdapter<String> adapter;
4. @Override
5. protected void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.activity_main);
8. list.add("B");list.add("A");list.add("D"); list.add("C");
9. //使用了一个系统自带的可以选中的布局
10. adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_checked, list);
11. setListAdapter(adapter);
12. //设置listview的选择模式
13. //设置多选
14. //getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
15. //设置单选
16. getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
17. }
18. //排序
19. public void onClick(View v){
20. //集合排序
21. Collections.sort(list);
22. //通知adapter更新
23. adapter.notifyDataSetChanged();
24. }
25.}