您的位置:首页 > 移动开发 > Android开发

android中进行布局管理界面_二、重写getView方法对按钮进行监听

2013-08-17 09:41 525 查看
按照惯例,首先上两张效果图。

原页面:



进行操作后的界面,进行了修改和删除操作。



首先还是先上传一下代码吧:

首先是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开发的那些人工作了,于是就放弃了。

下载链接:点击进入代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐