产品中要用到这个效果:listitem中带多选框,用来删除;有按钮,处理相应事件;item的click处理跳转。同事说这个设计操作起来很二,有点反社会,再加个图片和可以展开就反人类了。不管怎样,产品说了,我们就得做。
思路:item上有控件,就不能使item失去焦点,因此,各种button,checkbox就不能去获取焦点,但是可以click。其实主要就这些,其他也没多少东西。
1、首先贴个效果图,全选/取消全选,删除,item的单击,checkbox的单击,button的单击:
2、代码部分:
MainActivity.java
package com.ttdevs.lcb;
import java.util.LinkedList;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener2;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.ttdevs.lcb.CustomAdapter.ViewHolder;
public class MainActivity extends Activity implements OnClickListener, OnItemClickListener,
OnRefreshListener2<ListView> {
private LinkedList<ItemInfo> list;
private CustomAdapter adapter;
private PullToRefreshListView mPullRefreshListView;
private ListView actualListView;
private CheckBox cbSelectAll ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cbSelectAll = (CheckBox) findViewById(R.id.cbSelectAll);
mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
mPullRefreshListView.setMode(Mode.BOTH);
mPullRefreshListView.setOnRefreshListener(this);
actualListView = mPullRefreshListView.getRefreshableView();
// Need to use the Actual ListView when registering for Context Menu
registerForContextMenu(actualListView);
list = new LinkedList<ItemInfo>();
adapter = new CustomAdapter(getApplicationContext(), list);
initData(list);
actualListView.setAdapter(adapter);
actualListView.setOnItemClickListener(this);
}
private void initData(LinkedList<ItemInfo> list) {
for (int i = 0; i <= 20; i++) {
ItemInfo info = new ItemInfo();
info.setId(i);
info.setContent("这是第 " + i + " 条记录");
list.add(info);
adapter.getSelect().add(false);
info = null;
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ViewHolder holder = adapter.new ViewHolder();
holder.tvItemID = (TextView) view.findViewById(R.id.tvItemID);
holder.tvContent = (TextView) view.findViewById(R.id.tvContent);
// holder.cbSelect = (CheckBox) view.findViewById(R.id.cbSelect);
// holder.btClick = (Button) view.findViewById(R.id.btClick);
ItemInfo itemInfo = list.get(position);
itemInfo.setId(Integer.parseInt(holder.tvItemID.getText().toString()));
itemInfo.setContent(holder.tvContent.getText().toString());
Intent intent = new Intent(this, InfoActivity.class);
intent.putExtra("itemInfo", itemInfo);
startActivity(intent);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btDelete:
for (int i = 0; i < adapter.getSelect().size(); ) {
System.out.println(i+"|" + adapter.getSelect().get(i));
if(adapter.getSelect().get(i)){
adapter.getSelect().remove(i);
list.remove(i);
} else {
i++;
}
}
adapter.notifyDataSetChanged();
cbSelectAll.setChecked(false);
break;
case R.id.cbSelectAll:
boolean flag = cbSelectAll.isChecked();
for (int i = 0; i < adapter.getSelect().size(); i++) {
adapter.getSelect().set(i, flag);
}
adapter.notifyDataSetChanged();
break;
default:
break;
}
}
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
Toast.makeText(getApplicationContext(), "下拉刷新", Toast.LENGTH_LONG).show();
new GetLastTask().execute();
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
Toast.makeText(getApplicationContext(), "上拉获取更多", Toast.LENGTH_LONG).show();
new GetFirstTask().execute();
}
private class GetFirstTask extends AsyncTask<Void, Void, ItemInfo> {
@Override
protected ItemInfo doInBackground(Void... params) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ItemInfo info = new ItemInfo();
info.setId((int) (System.currentTimeMillis() % 1000000));
info.setContent("last:" + String.valueOf(System.currentTimeMillis()));
return info;
}
@Override
protected void onPostExecute(ItemInfo result) {
list.addLast(result);
adapter.getSelect().addLast(false);
adapter.notifyDataSetChanged();
// TODO 二选一?
mPullRefreshListView.onRefreshComplete();
super.onPostExecute(result);
}
}
private class GetLastTask extends AsyncTask<Void, Void, ItemInfo> {
@Override
protected ItemInfo doInBackground(Void... params) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ItemInfo info = new ItemInfo();
info.setId((int) (System.currentTimeMillis() % 1000000));
info.setContent("last:" + String.valueOf(System.currentTimeMillis()));
return info;
}
@Override
protected void onPostExecute(ItemInfo result) {
list.addFirst(result);
adapter.getSelect().addFirst(false);
adapter.notifyDataSetChanged();
mPullRefreshListView.onRefreshComplete();
super.onPostExecute(result);
}
}
}
CustomAdapter.java,这个是自定义的adapter,实现主要的逻辑:
package com.ttdevs.lcb;
import java.util.LinkedList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
public class CustomAdapter extends BaseAdapter {
private final LinkedList<Boolean> selected = new LinkedList<Boolean>();
private Context context;
private LayoutInflater inflater;
private LinkedList<ItemInfo> list;
public CustomAdapter(Context context, LinkedList<ItemInfo> list) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.list = list;
}
public LinkedList<Boolean> getSelect() {
return selected;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listview_item, null);
holder = new ViewHolder();
holder.cbSelect = (CheckBox) convertView.findViewById(R.id.cbSelect);
holder.tvContent = (TextView) convertView.findViewById(R.id.tvContent);
holder.tvItemID = (TextView) convertView.findViewById(R.id.tvItemID);
holder.btClick = (Button) convertView.findViewById(R.id.btClick);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ItemInfo itemInfo = list.get(position);
holder.tvItemID.setText(String.valueOf(itemInfo.getId()));
holder.tvContent.setText(itemInfo.getContent());
holder.cbSelect.setChecked(selected.get(position));
holder.cbSelect.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("selected set position:" + position);
selected.set(position, !selected.get(position));// 将CheckBox的选中状况记录下来
for (int i = 0; i < selected.size(); i++) {
System.out.println("selected " + i + ":" + selected.get(i));
}
// notifyDataSetChanged();
}
});
holder.btClick.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String value = String.valueOf(position) + "|" + itemInfo.getId() + "|" + itemInfo.getContent();
Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public class ViewHolder {
public CheckBox cbSelect;
public TextView tvContent;
public TextView tvItemID;
public Button btClick;
}
}
ItemInfo.java,一个传递数据的实体类:
package com.ttdevs.lcb;
import java.io.Serializable;
public class ItemInfo implements Serializable {
private static final long serialVersionUID = 6287420905418813028L;
private int id;
private String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
跳转结果页,看自己的业务了:
package com.ttdevs.lcb;
import android.app.Activity;
import android.os.Bundle;
public class InfoActivity extends Activity {
private ItemInfo info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_info);
// intent.putExtra("itemInfo", itemInfo);
info = (ItemInfo) getIntent().getExtras().get("itemInfo");
System.out.println(info.getId() + "||" + info.getContent());
}
}
布局文件:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/llSelectAll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/cbSelectAll"
android:layout_width="28dp"
android:layout_height="28dp"
android:onClick="onClick"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="8dp"
android:layout_toRightOf="@+id/cbSelectAll"
android:text="全选" />
<Button
android:id="@+id/btDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:onClick="onClick"
android:text="delete" />
</RelativeLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@android:color/holo_blue_dark" />
</LinearLayout>
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="@+id/pull_refresh_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/llSelectAll"
android:cacheColorHint="#00000000"
android:divider="#19000000"
android:dividerHeight="4dp"
android:fadingEdge="none"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:smoothScrollbar="true" />
</RelativeLayout>
listview的item,注意两个属性:clickable和focusable
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="30dip"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="4dp" >
<CheckBox
android:id="@+id/cbSelect"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:clickable="true"
android:focusable="false" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_toLeftOf="@+id/btClick"
android:layout_toRightOf="@+id/cbSelect"
android:orientation="vertical" >
<TextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="content" />
<TextView
android:id="@+id/tvItemID"
android:textColor="@android:color/black"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="id" />
</LinearLayout>
<Button
android:id="@+id/btClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="true"
android:focusable="false"
android:text="click" />
</RelativeLayout>
3、这里用到了一个下拉刷新的第三方库 com.handmark.pulltorefresh.library,这个在github上有的:
Demo:下载
先导入pulltorefresh library,然后再运行demo
4、有很多改进的地方,欢迎吐槽