在安卓工程中,很多时候都会用到下拉选单Spinner,ListView.有时候为了界面美观,操作方便,会在需求每个Item有一个删除或者其他按钮。本文旨在添加删除按钮,其他功能可以用类似的方法。
主布局文件,这里的btnAddSubject是用来添加新项的
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1"
android:gravity="center">
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/sprSubject"
android:layout_weight="1"/>
<ImageButton
android:id="@+id/btnAddSubject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@layout/image_button_style_add"
tools:ignore="ContentDescription" />
</LinearLayout>
Item的下拉style文件spinner_dropdown_style.xml
<?xml version="1.0" encoding="utf-8"?>
<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="30dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.9"
android:gravity="center">
<TextView
android:textAppearance="?android:attr/textAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/txtName" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnDelete"
android:src="@layout/image_button_style_delete"
tools:ignore="ContentDescription"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@android:color/darker_gray"/>
</LinearLayout>
选择项用系统默然即可,我这里用了一个简单布局spinner_style.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:textAppearance="?android:attr/textAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/txtName" />
</LinearLayout>
Spinner貌似不能用按钮,否则会导致无法选中,ListView貌似可以,有需要可以自行测试,我这里用的是ImageView。ImageView实现点击反馈,可以参考我转载的
虽然文中用的是ImageButton,但是Button,Image同样有效。
首先准备Adapter文件
package czhy.grey.sun.exam.bin.adapter_;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import czhy.grey.sun.exam.R;
import czhy.grey.sun.exam.bin.holder_.STHolder;
import czhy.grey.sun.exam.bin.question_.QuestionSubject;
import java.util.ArrayList;
public class SpinnerSubjectAdapter extends ArrayAdapter {
//数据
private ArrayList<QuestionSubject> list;
// 用来导入布局
private LayoutInflater inflater = null;
// 构造器
public SpinnerSubjectAdapter(ArrayList<QuestionSubject> list, Context context) {
super(context,R.layout.spinner_style);
this.list = list;
inflater = LayoutInflater.from(context);
}
public void setInflater(Context context){
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public QuestionSubject getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
STHolder holder;
QuestionSubject subject = getItem(position);
//下拉项
if (convertView == null) {
convertView = inflater.inflate(R.layout.spinner_dropdown_style, parent, false);
// 设置list中TextView的显示
holder = new STHolder(convertView);
convertView.setTag(holder);
}else {
holder = (STHolder) convertView.getTag();
}
holder.setName(subject.getSubjectName(),position);
holder.setDelete(subject.isEmpty());
return convertView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
STHolder holder;
QuestionSubject subject = getItem(position);
//选中显示
if (convertView == null) {
convertView = inflater.inflate(R.layout.spinner_style,parent,false);
// 设置list中TextView的显示
// 设置list中TextView的显示
holder = new STHolder(convertView);
convertView.setTag(holder);
}else {
holder = (STHolder) convertView.getTag();
}
holder.setName(subject.getSubjectName(),position);
return convertView;
}
public int size() {
return list.size();
}
}
以及Holder类
package czhy.grey.sun.exam.bin.holder_;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import czhy.grey.sun.exam.R;
import czhy.grey.sun.exam.bin.manager_.STManger;
public class STHolder {
private TextView txtName;
private ImageView btnDelete;
public STHolder(View convertView){
txtName = (TextView) convertView.findViewById(R.id.txtName);
btnDelete = (ImageView) convertView.findViewById(R.id.btnDelete);
}
public void setName(String name,int id) {
txtName.setText(name);
txtName.setTag(id);
}
public void setDelete(boolean isEmpty){
if(isEmpty){
btnDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
STManger.DeleteSubject((int)txtName.getTag());
STManger.NotifySubjectSetChanged();
}
});
}else {
btnDelete.setVisibility(View.INVISIBLE);
}
}
}
然后是准备数据,因为这些数据每个界面都有用到,而且基本不会改变,所有选择定义一个static类,以及我的类里面有两个数据项
package czhy.grey.sun.exam.bin.manager_;
import android.content.Context;
import android.database.Cursor;
import czhy.grey.sun.exam.bin.adapter_.SpinnerSubjectAdapter;
import czhy.grey.sun.exam.bin.adapter_.SpinnerTypeAdapter;
import czhy.grey.sun.exam.bin.question_.QuestionSubject;
import czhy.grey.sun.exam.bin.question_.QuestionType;
import java.util.ArrayList;
public class STManger {
private static ArrayList<QuestionSubject> subjectList;
private static SpinnerSubjectAdapter subjectAdapter;
private static ArrayList<QuestionType> typeList;
private static SpinnerTypeAdapter typeAdapter;
public STManger() {
subjectList = new ArrayList<>();
typeList = new ArrayList<>();
typeList.add(new QuestionType(0, "选择题型"));
subjectList.add(new QuestionSubject(null, "选择科目",false));//隐藏删除图标
DBManager.OpenDatabase();
Cursor cursor;
cursor = DBManager.GetTypeOrSubject("Type_");
while (cursor.moveToNext()) {
typeList.add(new QuestionType(Integer.parseInt(cursor.getString(0)), cursor.getString(1)));
}
cursor.close();
cursor = DBManager.GetTypeOrSubject("Subject_");
while (cursor.moveToNext()) {
subjectList.add(new QuestionSubject(cursor.getString(0), cursor.getString(1),Integer.parseInt(cursor.getString(2)) == 0));
}
cursor.close();
DBManager.CloseDatabase();
}
public static ArrayList<QuestionSubject> GetSubjectList() {
return subjectList;
}
public static ArrayList<QuestionType> GetTypeList() {
return typeList;
}
public static String GetSubject(String subjectCode) {
for (int i = 1; i< subjectList.size(); i++)
if(subjectList.get(i).getSubjectCode().equals(subjectCode))
return subjectList.get(i).getSubjectName();
return null;
}
public static void AddNewSubject(String code,String name) {
subjectList.add(new QuestionSubject(code,name,true));
DBManager.OpenDatabase();
DBManager.AddNewSubject(code,name);
DBManager.CloseDatabase();
}
public static int GetTypeCode(String typeName) {
for (QuestionType type:typeList)
if(type.getTypeName().equals(typeName))
return type.getTypeCode();
return 0;
}
public static void SetInflater(Context context){
if(subjectAdapter != null) {
subjectAdapter.setInflater(context);
typeAdapter.setInflater(context);
}
else {
subjectAdapter = new SpinnerSubjectAdapter(subjectList, context);
typeAdapter = new SpinnerTypeAdapter(typeList,context);
}
}
public static SpinnerSubjectAdapter GetSubjectAdapter(){
return subjectAdapter;
}
public static void NotifySubjectSetChanged() {
subjectAdapter.notifyDataSetChanged();
}
public static void DeleteSubject(int id) {
DBManager.OpenDatabase();
DBManager.DeleteSubject(subjectList.get(id).getSubjectCode());
DBManager.CloseDatabase();
subjectList.remove(id);
}
public static SpinnerTypeAdapter GetTypeAdapter(){
return typeAdapter;
}
public static void UpdateSubjectList() {
subjectList.clear();
subjectList.add(new QuestionSubject(null, "选择科目",false));//隐藏删除图标
DBManager.OpenDatabase();
Cursor cursor = DBManager.GetTypeOrSubject("Subject_");
while (cursor.moveToNext()) {
subjectList.add(new QuestionSubject(cursor.getString(0), cursor.getString(1),cursor.getInt(2) == 0));
}
cursor.close();
DBManager.CloseDatabase();
}
}
数据封装类
package czhy.grey.sun.exam.bin.question_;
public class QuestionSubject {
private String subjectCode;
private String subjectName;
private boolean isEmpty;
public QuestionSubject(String subjectCode, String subjectName,boolean isEmpty){
this.subjectCode = subjectCode;
this.subjectName = subjectName;
this.isEmpty = isEmpty;
}
public String getSubjectCode() {
return subjectCode;
}
public String getSubjectName() {
return subjectName;
}
public boolean isEmpty() {
return isEmpty;
}
}
最后直接引用设置即可
STManger.SetInflater(this);
(findViewById(R.id.btnAddSubject)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
InputDialog inputDialog = new InputDialog(ImportActivity.this, new View.OnClickListener() {
@Override
public void onClick(View v) {
InputDialog dialog = (InputDialog) v.getTag();
STManger.AddNewSubject(dialog.getCode(),dialog.getName());
((Spinner)findViewById(R.id.sprSubject)).setSelection(STManger.GetSubjectAdapter().size() - 1);
dialog.setInput(false);
dialog.cancel();
}
});
inputDialog.setTitle("请输入科目");
inputDialog.show();
}
});
Spinner spinner = (Spinner) findViewById(R.id.sprSubject);
spinner.setAdapter(STManger.GetSubjectAdapter());
但对于ListView来说,用static就不合适,表格有的时候要显示庞大的数据,以及需要显示不同的类别
这里可以参考我的InputDialog类,在Adapter里定义一个setOnClickListener(View.OnClickListener listener)方法
在Holder里定义setOnClickListener(View.OnClickListener listener)方法
这是InputDialog的源码
package czhy.grey.sun.exam.bin.dialog_;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import java.util.ArrayList;
import czhy.grey.sun.exam.R;
import czhy.grey.sun.exam.bin.manager_.STManger;
import czhy.grey.sun.exam.bin.question_.QuestionSubject;
public class InputDialog extends Dialog {
private boolean isInput;
private EditText txtName;
private String code;
private View.OnClickListener listener;
public InputDialog(Context context,View.OnClickListener listener) {
super(context);
this.listener = listener;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_dialog_input);
txtName = (EditText)findViewById(R.id.txtName);
txtName.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
isInput = true;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(txtName.getText().length()==0)
isInput = false;
}
});
ArrayList<String> list = new ArrayList<>();
final char chCode = 'A';
for(int i=0;i<26;i++){
list.add((char)((int)chCode+i)+"");
}
for(QuestionSubject subject: STManger.GetSubjectList()){
list.remove(subject.getSubjectCode());
}
Spinner spinner = (Spinner)findViewById(R.id.sprCode);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
code = parent.getAdapter().getItem(position).toString();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
code = parent.toString();
}
});
spinner.setAdapter(new ArrayAdapter<>(getContext(),R.layout.support_simple_spinner_dropdown_item,list));
findViewById(R.id.btnAdd).setTag(this);
findViewById(R.id.btnAdd).setOnClickListener(listener);
findViewById(R.id.btnCancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isInput = false;
cancel();
}
});
}
public void setInput(boolean input) {
isInput = input;
}
public String getName() {
return txtName.getText().toString();
}
public String getCode() {
return code;
}
@Override
public void cancel() {
if(!isInput)
super.cancel();
}
}
相关连接:
ImageButton 点击反馈