zoukankan      html  css  js  c++  java
  • [置顶] 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;
    		}
    	}
    }
    

     

  • 相关阅读:
    Leetcode Binary Tree Level Order Traversal
    Leetcode Symmetric Tree
    Leetcode Same Tree
    Leetcode Unique Paths
    Leetcode Populating Next Right Pointers in Each Node
    Leetcode Maximum Depth of Binary Tree
    Leetcode Minimum Path Sum
    Leetcode Merge Two Sorted Lists
    Leetcode Climbing Stairs
    Leetcode Triangle
  • 原文地址:https://www.cnblogs.com/riskyer/p/3299440.html
Copyright © 2011-2022 走看看