GridView学习
来源:互联网 发布:淘宝 买飞机 编辑:程序博客网 时间:2024/06/01 09:48
(1)GridView学习总结
GridView使用上和ListView十分相似。
GridViewmGridView=(GridView)findViewById(R.id.gridview);
CustomAdaptermAdapter=newCustomAdapter(MainActivity.this,R.layout.item,List<Custom>);
mGridView.setAdaper(mAdapter);
我们需要先思考,在res/layout目录下建立一个item.xml。它代表着ListView或者GridView中每一部分的布局。
我们需要自定义两个类,一个是Custom.一个是适配器CustomAdapter(要继承于ArrayAdapter)
先说item.xml
假设需要一个TextView和一个Button
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/newbutton"/>
</LinearLayout>
先说Custom类,它的成员变量要与item.xml需要的自定义的属性一一对应。
publicclass Custom{
privateString textName; //对应item.xml中的TextView的文字内容
privateButton buttonName;//对应item.xml中的Button的文字内容
//使用带形参的构造方法,直接可以在初始化类的时候给成员变量赋值。
publicCustom(String textName,String buttonName){
this.textName=textName;
this.buttonName=buttonName;
}
//提供若干get方法方便其他类获取到Custom类的相关属性。
publicString getTextName(){
returntextName;
}
publicString getButtonName(){
returnbuttonName;
}
}
再说CustomAdapter类
publicclass CustomAdapter extends ArrayAdapter<Custom>{
privateint resouceId;//这个resouceId指的就是item.xml的id。就是R.layout.item.
PublicCustomAdapter(Context context,int resource,List<Custom>objects){
super(context,resource,objects);
resourceId=resource;
}
//getView方法主要是给item.xml的各个控件赋予属性值
publicView getView(int position, ViewconvertView, ViewGroup parent) {
//TODOAuto-generated method stub
StringtextName=getItem(position).getTextName();//getItem()方法返回List<Custom>的Custom对象
StringbuttonName=getItem(position).getButtonName();
LayoutInflatermInflater=LayoutInflater.from(getContext());
Viewview=mInflater.inflate(resourceId,null);
TextViewmTextView=(TextView)view.findViewById(R.id.textview);
ButtonmButton=(Button)view.findViewById(R.id.button);
mTextView.setText(textName);
mButton.setText(buttonName);
returnview;
}
}
最后MainActivity中
List<Custom>mList = newArrayList<Custom>();
GridViewmGridView;
mGridView= (GridView) findViewById(R.id.shit);
CustomAdaptermAdapter = newCustomAdapter(MainActivity.this,R.layout.item,mList);
init();
mGridView.setAdapter(mAdapter);
(2)ListView和GridView的点击事件
根据形参intpositon可以获取到数组或者集合的位置。
mListView1.setOnItemClickListener(newOnItemClickListener() {
@Override
publicvoidonItemClick(AdapterView<?> parent, View view,intposition,longid) {
//TODOAuto-generated method stub
if(mStrings[position].equals("onlytext")){
Toast.makeText(MainActivity.this,"notprovide",Toast.LENGTH_SHORT).show();
}
if(mStrings[position].equals("textand pictore")){
IntentmIntent=newIntent();
mIntent.setClass(MainActivity.this,FirstActivity.class);
startActivity(mIntent);
}
if(mStrings[position].equals("customview")){
}
Log.e("AdapterView<?>",parent + "");
Log.e("View",view + "");
Log.e("position",position + "");
Log.e("id",id + "");
}
});
(3)GridView,ListView探索。
GridView,ListView均继承于AbsListView。AbsListView重写了onTouchEvent方法。
首先明确GridView是容器。我们自定义的item假设是一个RelativeLayout中放一个Button.一般容器是默认不拦截事件的。所以事件会从GridView分发到RelativeLayout然后到Button.因为Button默认clickable为true.导致Button的onTouchEvent返回true,进而导致Button的dispatchTouchEvent返回true.不会执行容器的dispatchTouchEvent.而我们想要调用GridView的setOnItemClickListener这个方法。我们需要让事件分发到GridView.我们可以把GridView的每个部分理解成A容器--B容器--C组件。也就是要让事件分发到A容器。
所以我们把Button的android:clickable属性设置为false.默认Button的longClickable属性也是false.默认onTouch方法也是返回false.
此时事件从C组件分发到B容器,B容器是我们用的 RelativeLayoutorLinearLayout.不设置监听事件的话,会继续分发到A容器。
我们发现此时GridView的setOnItemClickListener依然没有生效。原因是因为GridView和ListView继承的AbsListView重写了onTouchEvent.
查看源码,可以发现AbsListView的onTouchEvent中
publicbooleanonTouchEvent(MotionEvent ev) {
….
caseMotionEvent.ACTION_UP:{
onTouchUp(ev);
break;
….
}
privatevoidonTouchUp(MotionEvent ev) {
….
if(inList && !child.hasFocusable()) {
if(mPerformClick==null){
mPerformClick=newPerformClick();
}
….
if(!mDataChanged && mAdapter.isEnabled(motionPosition)){
mTouchMode=TOUCH_MODE_TAP;
setSelectedPositionInt(mMotionPosition);
layoutChildren();
child.setPressed(true);
positionSelector(mMotionPosition,child);
setPressed(true);
…..
mTouchModeReset=newRunnable() {
@Override
publicvoidrun() {
mTouchModeReset=null;
mTouchMode=TOUCH_MODE_REST;
child.setPressed(false);
setPressed(false);
if(!mDataChanged && isAttachedToWindow()) {
performClick.run();
}
}
};
….
}
...}
源码中标示出!child.hasFocusable()要为true才能响应点击事件。也就是B容器,C组件不能获得焦点。
所以想要事件分发到A容器。我们还要把Button的android:focusable属性设置为false.B容器默认focusable为false.(待确认下,应该是的)
也就是Button中以下属性要确认,clickable为false,longClickabel为false,focusable为false.
我们发现可以响应GridView的setOnItemClickListener后,但是C组件竟然也有按下和释放的效果了。
明明我们在设置clickable为false,longClickabel为false后就应该Button无法点击,一直处于未点击的效果不变的。
原因是源码中有child.setPressed(true)和child.setPressed(false).
而且源码中有setPressed(true)和setPressed(false).
所以A容器,B容器,C组件(可以是多个,已经验证,但要设置好让事件分发到A容器)都会有按下和释放的效果,如果你有设置。
(4)GridView高度自适应
1.把GridView对象送到Adapter中。
2.在Adapter的getView中获取到GridView的高度。
3.GridView的高度除以n得到n部分的高度。
4.将每部分的高度设置给item.
classCustomAdapterextendsArrayAdapter<FunctionItem> {
privateintresourceId;
GridViewmm;
publicCustomAdapter(Context context, intresource,
List<FunctionItem>objects,GridView gridView) {
super(context,resource, objects);
resourceId= resource;
mm=gridView;
//TODOAuto-generated constructor stub
}
publicView getView(intposition, View convertView, ViewGroup parent) {
//TODOAuto-generated method stub
LayoutInflatermInflater = LayoutInflater.from(getContext());
Viewview = mInflater.inflate(resourceId,null);
ViewmView=(View)view.findViewById(R.id.item_rel);
LayoutParamsmLayoutParams=mView.getLayoutParams();
mLayoutParams.height=mm.getHeight()/3-4;
returnview;
}
(5)GridView,ListView的android:descendantFocusability属性
android:descendantFocusability=“xxx”;
xxx可以为:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点。原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。
找时间写个demo三个都试试。一般应该第一个和第三个用的多。应该就是与事件分发有关,之前解决过GridView的点击问题的。
实测,这个属性并不是写在listView控件中的,而是ListView对应的item.xml的容器中的。切记!
- GridView学习
- 学习gridview
- GridView 学习
- GridView学习
- gridview学习
- GridView学习
- GridView--学习
- GridView学习
- GridView学习
- 学习gridview的使用
- GridView 学习(转)
- GridView 学习(转)
- GridView备用学习
- android GridView学习笔记
- android学习之-GridView
- GridView学习记录
- android GridView的学习
- GridView的学习总结
- opencv310配置链接库 debug版和release版
- java代码测试网络是否联通
- fcntl获取和修改文件打开状态标志
- FastJson学习随笔
- hadoop集群基本配置及启动
- GridView学习
- Fragment 2
- boost mutex lock 使用
- 限制范围的拖拽
- 【java基础】String、StringBuilder和StringBuffer的区别
- LabVIEW自带函数实现SQL Server操作(下)
- linux安装mysql数据库
- 关于 Android studio的Gradle 那些坑
- MySQL优化实例