android中进行布局管理界面_二、重写getView方法对按钮进行监听
2013-08-17 09:41
525 查看
按照惯例,首先上两张效果图。
原页面:
进行操作后的界面,进行了修改和删除操作。
首先还是先上传一下代码吧:
首先是listview的布局文件:
其中
PS:这里其实我们可以做一个例子来试一试,我们给listview添加一个列监听。
于是有的人就说其实是这控件里面的button消耗了该事件,需要重写button里面的监听才可以。刚开始的时候我也深信这理论,但是重写button里面的监听事件之后(就是监听里面最后返回false,让其往上层传送监听事件)还是没有任何效果。我就有点怀疑了。
最后搜了一下资料,发现这理论其实是不正确的,我们做一个实验就可以了,我们点击这一列,但是不选择按钮的范围,这样产生的事件是不会经过button的,一样是没有效果的。这就说明这个理论其实是不对的。虽然安卓里面的事件信号传递的确是由下层往上层传的,但是默认我觉得应该是传false(就是不阻止信号往上层传递)的,这样才更符合实际需求。
其实真正的原因是button抢夺了listView的焦点,
我们在listView里面的button里面填上如下两句:
android:clickable="true"
android:focusable="false"
就能让父级组件也能获取焦点了。
例:
好了,回归正题。继续主线,下面是我重写的SimpleAdapter类:
所以这里就是用handler传参数来进行处理。
下面是弹出框类:
附上一张弹出框效果图:
有点丑哈,不过将就能用就行了
至此大功告成。
其实本来还想把list_layout改成类的形式的,但是后来发现这个难度太高了,等同于做一遍SDK开发的那些人工作了,于是就放弃了。
下载链接:点击进入代码下载
原页面:
进行操作后的界面,进行了修改和删除操作。
首先还是先上传一下代码吧:
首先是listview的布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/RelativeLayout01" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" > <TextView android:id="@+id/showuser" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12sp" /> <Button android:id="@+id/deltebtn" android:layout_width="65dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="75dp" android:clickable="true" android:focusable="false" android:textSize="12sp" /> <Button android:id="@+id/updatebtn" android:layout_width="65dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="5dp" android:clickable="true" android:focusable="false" android:textSize="12sp" /> </RelativeLayout>
public class MainActivity extends Activity { ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview=(ListView) findViewById(R.id.ListView); //生成动态数组,加入数据 ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>(); for(int i=0;i<10;i++) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("showUser","UserMessage:"+i);//存储用户的信息 map.put("deleteBtn", "删除"+i); //添加删除按钮名称 map.put("updateBtn", "更新"+i); //添加更新按钮名称 listItem.add(map); } //生成适配器的Item和动态数组对应的元素 MySimpleAdapter listItemAdapter = new MySimpleAdapter(this,listItem,//数据源 R.layout.list_layout,//ListItem的XML实现 //动态数组与ImageItem对应的子项 new String[] {"showUser","deleteBtn", "updateBtn"}, //list_lauouym的XML文件里面的一个TextView,两个Button的资源ID new int[] {R.id.showuser,R.id.deltebtn,R.id.updatebtn}); //添加并且显示 listview.setAdapter(listItemAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
其中
MySimpleAdapter 是我继承SimpleAdpter自己重写的。
PS:这里其实我们可以做一个例子来试一试,我们给listview添加一个列监听。
listview.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view,int position, long id) { Toast.makeText(this, "点击了第"+++position+"行", Toast.LENGTH_SHORT).show(); } }); } }这里我们其实可以发现,添加了这一句之后是没有任何监听效果的,但是如果把button改为了TextView,点击这一列的时候就会发现产生了监听效果。
于是有的人就说其实是这控件里面的button消耗了该事件,需要重写button里面的监听才可以。刚开始的时候我也深信这理论,但是重写button里面的监听事件之后(就是监听里面最后返回false,让其往上层传送监听事件)还是没有任何效果。我就有点怀疑了。
最后搜了一下资料,发现这理论其实是不正确的,我们做一个实验就可以了,我们点击这一列,但是不选择按钮的范围,这样产生的事件是不会经过button的,一样是没有效果的。这就说明这个理论其实是不对的。虽然安卓里面的事件信号传递的确是由下层往上层传的,但是默认我觉得应该是传false(就是不阻止信号往上层传递)的,这样才更符合实际需求。
其实真正的原因是button抢夺了listView的焦点,
我们在listView里面的button里面填上如下两句:
android:clickable="true"
android:focusable="false"
就能让父级组件也能获取焦点了。
例:
<Button android:id="@+id/deltebtn" android:layout_width="65dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="75dp" android:clickable="true" android:focusable="false" android:textSize="12sp" />
好了,回归正题。继续主线,下面是我重写的SimpleAdapter类:
public class MySimpleAdapter extends SimpleAdapter { private Context context; private final static int BUTTON_UPDATE=100; private final static int BUTTON_DELETE=200; ArrayList<HashMap<String, Object>> listItem; public MySimpleAdapter(Context context, ArrayList<HashMap<String, Object>> data, int resource, String[] from, int[] to) { super(context, data, resource, from, to); this.context=context; listItem=data; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub final int mPosition = position; convertView = super.getView(position, convertView, parent); Button deltebtn = (Button) convertView .findViewById(R.id.deltebtn);// id为你自定义布局中按钮的id deltebtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub mHandler.obtainMessage(BUTTON_DELETE, mPosition, 0) .sendToTarget(); System.out.println("点击删除按钮"); } }); Button updateBtn = (Button) convertView .findViewById(R.id.updatebtn); updateBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub mHandler.obtainMessage(BUTTON_UPDATE, mPosition, 0) .sendToTarget(); } }); return convertView; } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch (msg.what) { case BUTTON_UPDATE: System.out.println("你更新第" + (msg.arg1 + 1) + "按钮"); openOptionsDialog(listItem,msg.arg1); System.out.println("发生变化"); //下面这个方法已经被移动到updateDialog中调用了。 // notifyDataSetChanged();// 这个函数很重要,告诉Listview适配器数据发生了变化 // mShowInfo.setText("你点击了第" + (msg.arg1 + 1) + "按钮"); break; case BUTTON_DELETE: listItem.remove(msg.arg1); // mShowInfo.setText("你删除了第" + (msg.arg1 + 1) + "行"); System.out.println("你删除了第" + (msg.arg1 + 1) + "行"); notifyDataSetChanged(); break; } } }; private void openOptionsDialog(ArrayList<HashMap<String, Object>> listItem, int line) { // 生成对话框 AlertDialog dlg = new AlertDialog.Builder(context).create(); //显示对框框 dlg.show(); Window window = dlg.getWindow(); //添加自定义的Layout以及布局方式,注意传入dlg对象本身方便关闭该提示框 window.addContentView(new UpdateDialog(context,this,dlg,listItem,line),new LayoutParams(-1, -1)); } }这里需要说明的一点是对listItem的操作不能放在onCreate方法里面(当然包括onCreate所调用的那些方法了),因为所有的行的id都是一样的,放在onCreate方法里面的话熊是分辨不出要删除哪一个的,否则是会报错空指针的。
所以这里就是用handler传参数来进行处理。
下面是弹出框类:
package com.example.listviewtest; import java.util.ArrayList; import java.util.HashMap; import android.app.AlertDialog; import android.content.Context; import android.graphics.Color; import android.text.Editable; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.TextView; public class UpdateDialog extends RelativeLayout{ private Context context; private AlertDialog dlg; private ArrayList<HashMap<String, Object>> listItem; private int line; private MySimpleAdapter mySimpleAdapter; private RelativeLayout layout; private TextView advicemsg; private EditText updateedit; private Button ok; private Button canel; private int advicemsgId=101; private int updateeditId=102; private int okId=103; private int canelId=104; public UpdateDialog(Context context, MySimpleAdapter mySimpleAdapter, AlertDialog dlg, ArrayList<HashMap<String, Object>> listItem, int line) { super(context); this.context=context; this.mySimpleAdapter=mySimpleAdapter; this.dlg=dlg; this.listItem=listItem; this.line=line; init(); } private void init() { layout=new RelativeLayout(context); layout.setBackgroundColor(Color.CYAN); LayoutParams lp=new LayoutParams(300,200); lp.addRule(RelativeLayout.CENTER_IN_PARENT); advicemsg=new TextView(context); advicemsg.setText("输入新用户信息"); advicemsg.setId(advicemsgId); LayoutParams lpadvicemsg=new LayoutParams(-2,-2); lpadvicemsg.addRule(RelativeLayout.ALIGN_PARENT_TOP); lpadvicemsg.addRule(RelativeLayout.CENTER_HORIZONTAL); lpadvicemsg.setMargins(0, 10, 0, 0); //输入新的信息 updateedit=new EditText(context); updateedit.setId(updateeditId); LayoutParams lpupdateedit=new LayoutParams(200,60); lpupdateedit.addRule(RelativeLayout.CENTER_HORIZONTAL); lpupdateedit.addRule(RelativeLayout.BELOW,advicemsgId); lpupdateedit.setMargins(0, 10, 0, 0); ok=new Button(context); ok.setText("确定"); LayoutParams lpok=new LayoutParams(-2,-2); lpok.addRule(RelativeLayout.BELOW,updateeditId); lpok.addRule(RelativeLayout.ALIGN_PARENT_LEFT); lpok.setMargins(10, 10, 0, 0); //添加取消按钮 canel=new Button(context); canel.setText("取消"); LayoutParams lpcanel=new LayoutParams(-2,-2); lpcanel.addRule(RelativeLayout.BELOW,updateeditId); lpcanel.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); lpcanel.setMargins(0, 10, 10, 0); layout.addView(advicemsg, lpadvicemsg); layout.addView(updateedit,lpupdateedit); layout.addView(ok,lpok); layout.addView(canel, lpcanel); addView(layout,lp); ok.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String str = updateedit.getText().toString(); HashMap<String, Object> hashMap = listItem.get(line); hashMap.put("showUser", str); mySimpleAdapter.notifyDataSetChanged(); System.out.println("确定"); dlg.cancel(); } }); canel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out.println("取消弹出框"); dlg.cancel(); } }); } }
附上一张弹出框效果图:
有点丑哈,不过将就能用就行了
至此大功告成。
其实本来还想把list_layout改成类的形式的,但是后来发现这个难度太高了,等同于做一遍SDK开发的那些人工作了,于是就放弃了。
下载链接:点击进入代码下载
相关文章推荐
- 一种使用Xml对Android界面进行动态布局的方法
- android:一个listview多个item布局时,需注意重写getViewTypeCount()方法
- android中进行布局管理界面_一、利用ListView进行布局
- Android界面之----自定义的Dialog,然后利用回调方法,在调用处,进行Dialog中各按钮的事件处理。
- androidの设计的布局在阿拉伯语下界面错乱的解决方法
- androidの设计的布局在阿拉伯语下界面错乱的解决方法 总汇
- android getView方法不执行的一个原因是布局文件中没有给列表显示的位置
- Android项目:模仿ConvertView原理(ListView的getView方法)对View对象进行回收和复用 推荐
- gojs 进行监听删除事件及重写监听方法时调用原有方法
- Android N版本 设置深层界面无法监听按键事件解决方法!
- Android 重写lisview的adapter的getView方法,position一直是0
- 【Android基础篇】重写SimpleAdapter的getView以实现按钮点击响应
- Android 程式开发:(十一)监听UI事件 —— 11.1重写Activity中的方法
- Android中对按钮的监听方法总结
- androidの设计的布局在阿拉伯语下界面错乱的解决方法 总汇
- android 监听整个界面加载完成的方法
- android设计的布局在阿拉伯语下界面错乱的解决方法
- android getView方法不执行的一个原因是布局文件中没有给列表显示的位置
- android设计的布局在阿拉伯语下界面错乱的解决方法
- Android编程双重单选对话框布局实现与事件监听方法示例