• [置顶] Android常用适配器控件


    Android常用适配器控件

          列表控件用于显示数据集合,Android不是使用一种类型的控件管理显示和数据,而是将这两项功能分布用列表控件和适配器来实现。列表控件扩展了android.widget.AdapterView的类,包括ListView、GridView、Spinner和Gallery。

    1)基本的列表控件ListView

        ListView控件垂直显示一组项,通常通过编写一个扩展android.app.ListActivity的新活动来使用ListView。ListActivity包含一个ListView,可以调用setListAdapter()方法来为ListView设置数据。前面介绍过适配器将列表控件链接到数据,帮助为列表控件准备子视图,可单击ListView中的某一项来立即执行操作,或选择它们以稍后对所选择项集合采取操作。

    Demo1:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin" >
    
        <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1" >
        </ListView>
    
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="doClick"
            android:text="Submit Selection" >
        </Button>
    
    </LinearLayout>


       我们通过改写系统的提供的布局android.R.layout.list,向其中添加一个Button。注意:这里ListView的ID的规范:必须使用@android:id/list,因为ListActivity需要在布局中找到一个R.layout.list的ListView。

       其次还需要注意的是:在布局LinearLayout中指定的ListView的高度,我们希望Button永远显示在在屏幕上,无论ListView中有多少项,我们不希望滚动到页面底部才能看到按钮。所以这里ListView的layout_height设置为0,然后使用layout_weight表面此空间应该占据父容器中的所有可用空间,同时为Button预留了空间。

      最后我们未Button按钮添加了一个响应函数doClick。所以在我们的MainActivity中需要实现doClick方法。

    代码清单:

    public class MainActivity extends ListActivity {
    	
    	private ListView lv = null;
    	private Cursor cursor;
    	private int idCol = -1;
    	private int nameCol = -1;
    	private int noteCol = -1;
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.list);
    		
    		lv = getListView();
    		cursor = managedQuery(People.CONTENT_URI, null, null, null, People.NAME);
    		String cols[] = new String[] {People.NAME};
    		int [] views = new int[] {android.R.id.text1};
    		
    		idCol = cursor.getColumnIndex(People._ID);
    		nameCol = cursor.getColumnIndex(People.NAME);
    		noteCol = cursor.getColumnIndex(People.NOTES);
    		
    		SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_multiple_choice,
    				cursor, cols, views);
    		
    		this.setListAdapter(adapter);	
    		
    		lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    	}
    	
    	public void doClick(View view) {
    		int count = lv.getCount();
    		SparseBooleanArray viewItems = lv.getCheckedItemPositions();
    		for(int i = 0; i < count; i++) {
    			if(viewItems.get(i)) {
    				cursor.moveToPosition(i);
    				long id = cursor.getLong(idCol);
    				String name = cursor.getString(nameCol);
    				String notes = cursor.getString(noteCol);
    				Toast.makeText(this, "info: id="+id+" name="+name+" notes="+notes, Toast.LENGTH_LONG).show();
    			}
    		}
    	}
    }

       代码中:我们首先调用setContentView()方法设置活动的用户界面,在适配器的设置中我们为ListView的每一行传递了Android所提供了另一个视图android.R.layout.simple_list_item_multiple_choice,这将导致导致每一行拥有一个TextView与一个CheckBox。通过查看这个布局文件,将会看到其实是CheckedTextView,继承于TextView,这个特殊的TextView专门用于ListView的。它的TextView的ID为android.R.id.text1。

      为了让用户能够选择多行,我们设置了ListView.CHOICE_MODE_MULTIPLE属性。

      最后为了实现用于提交功能我们添加了一个Button,并为其添加了响应方法doClick。在doClick()方法中我们调用ListView.getCheckedItemPositions()返回一个boolean类型数组,表面是否选择了某一项。然后我们迭代ListView所有项,如果选择了相应行,viewItems.get(i)将返回true。当从ListView获得已经选择的位置编号之后我们就可以使用Cursor的moveToPosition()移动到相应位置读取数据了。

    2)网格控件GridView

        Android有一个GridView控件可通过网格的形式显示信息。GridView的使用模式是首先在布局文件中定义网格,然后使用android.widget.ListAdapter将数据绑定到网格。下面我们同样以显示联系人为Demo,只不过这次是以网格的形式显示出来:

    <GridView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/grid"
        android:padding="10dp"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:numColumns="auto_fit"
        android:columnWidth="100dp"
        android:stretchMode="columnWidth"
        android:gravity="center">
    </GridView>
    public class MainActivity extends Activity {
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		GridView gv = (GridView)this.findViewById(R.id.grid);
    		Cursor cursor = managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.Contacts.DISPLAY_NAME);
    		String cols[] = new String[] {ContactsContract.Contacts.DISPLAY_NAME};
    		int [] views = new int[] {android.R.id.text1};
    		
    		int idCol = cursor.getColumnIndex(ContactsContract.Contacts._ID);
    		int nameCol = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
    		int noteCol = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_SOURCE);
    		
    		SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1,
    				cursor, cols, views);
    		
    		gv.setAdapter(adapter);
    	}
    }


      网格显示了设备上联系人的姓名。代码中MainActivity扩充了Activity,而不是ListActivity,然后使用setContentView()来设置GridView的布局,最后为了设置适配器,我们调用了GridView的setAdapter()方法。注意:网格使用的适配器是ListAdapter,由于列表是一维的,而网格是二维的,所以网格实际上显示了面向列表的数据。

    3)下拉框控件Spinner

       Spinner就像一个下拉菜单,通常用于从相对较短的选择列表中进行选择,如果选择列表太长,会自动添加一个滚动条。我们可以通过XML布局简单实例化Spinner。

    <Spinner
    	android:id="@+id/spinner"
    	android:prompt="@string/spinnerPrompt"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content" />

      下拉框控件在静止时显示一个值,当用户单击小箭头时,显示一个列表提供给用户选择一个新值。填充此列表的方式和填充其他列表控件的方式相同,都是使用适配器。

    public class MainActivity extends Activity {
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    
    		setContentView(R.layout.spinner);
    		
    		Spinner spinner = (Spinner)this.findViewById(R.id.spinner);
    		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets, android.R.layout.simple_spinner_item);
    		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    		spinner.setAdapter(adapter);
    	}
    }
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string-array name="planets">
        	<item>Monday</item>
        	<item>Tuesday</item>
        	<item>Wednesday</item>
        	<item>Thursday</item>
        	<item>Friday</item>
        	<item>Saturday</item>
        	<item>Sunday</item>
        </string-array>
    </resources>


       代码中首先通过setContentView来设置当前布局,然后找到相应的Spinner。通过ArrayAdapter.createFromResource()定义了微调框在正常模式下的外观,然后使用adapter.setDropDownViewResource()设置弹出列表模式的微调框。

     

    4)水平滚动的列表控件Gallery

        Gallery控件是一种可水平滚动的列表控件,焦点始终位于列表中央,此控件通常在触摸屏模式下用在相册,既可以通过XML布局也可以通过代码实例化Gallery。

    <Gallery
    	android:id="@+id/gallery"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    />

       Gallery控件通常用于显示图像,所以适配器可能会针对图像特殊化,为此Android提供了一个名为BaseAdapter的抽象类,我们通过扩展它,自定义适配器。

    Demo:

    <GridView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:id="@+id/gridView"
        android:padding="10dp"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:numColumns="auto_fit"
        android:gravity="center">
    </GridView>

      activity_main.xml中有一个主要布局,其中包含了一个GridView定义,我们需要从该布局获取GridView的引用。然后实例化一个MyAdapter,继承于BaseAdapter。

    public class MainActivity extends Activity {
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		GridView gv = (GridView)this.findViewById(R.id.gridView);
    		MyAdapter adapter = new MyAdapter(this);
    		gv.setAdapter(adapter);
    		
    	}
    	
    	public class MyAdapter extends BaseAdapter {
    		private int convertViewCounter = 0;
    		private Context context;
    		private LayoutInflater inflater;
    		
    		private int imgId[] = {R.drawable.img1, R.drawable.img2, R.drawable.img3,
    				R.drawable.img4, R.drawable.img5, R.drawable.img6};
    		private Bitmap[] images = new Bitmap[imgId.length];
    		private Bitmap[] Thumbs = new Bitmap[imgId.length];
    		
    		class ViewHolder {
    			ImageView image;
    		}
    		
    		public MyAdapter(Context context) {
    			// TODO Auto-generated constructor stub
    			this.context = context;
    			inflater = LayoutInflater.from(context);
    			
    			for(int i = 0; i < imgId.length; i++) {
    				images[i] = BitmapFactory.decodeResource(context.getResources(), imgId[i]);
    				Thumbs[i] = Bitmap.createScaledBitmap(images[i], 100, 100, false);
    			}
    		}
    		
    		@Override
    		public int getCount() {
    			// TODO Auto-generated method stub
    			return imgId.length;
    		}
    
    		@Override
    		public Object getItem(int position) {
    			// TODO Auto-generated method stub
    			return images[position];
    		}
    
    		@Override
    		public long getItemId(int position) {
    			// TODO Auto-generated method stub
    			return position;
    		}
    
    		@Override
    		public View getView(int position, View convertView, ViewGroup parent) {
    			// TODO Auto-generated method stub
    			ViewHolder holder;
    			if(convertView == null) {
    				convertView = inflater.inflate(R.layout.gridimage, null);
    				convertViewCounter++;
    				
    				holder = new ViewHolder();
    				holder.image = (ImageView)convertView.findViewById(R.id.gridImageView);
    				convertView.setTag(holder);
    			} else {
    				holder = (ViewHolder)convertView.getTag();
    			}
    
    			holder.image.setImageBitmap(Thumbs[position]);
    			return convertView;
    		}
    	}
    }
    

     

  • 相关阅读:
    实验 4:Open vSwitch 实验——Mininet 中使用 OVS 命令
    实验 2:Mininet 实验——拓扑的命令脚本生成
    软工第一次作业——自我介绍
    博客园美化
    实验 1:Mininet 源码安装和可视化拓扑工具
    软工实践个人总结
    结对编程之学术家族树
    软件工程实践结对编程作业(需求分析与原型设计)
    软件工程实践个人编程作业
    软件工程实践第一次个人作业
  • 原文地址:https://www.cnblogs.com/riskyer/p/3299440.html
Copyright © 2020-2023  润新知