在Android的ListView的纱厂,我必须用一个ViewHolder? [英] Android Spinners in ListView, do I have to use a ViewHolder?
问题描述
我有一个的ListView
与纱厂
的问题。我有一个的ListView
与复选框
,标签和两个纱厂
。在微调
从SQLite的居住和工作正常。我没有使用 ViewHolder
方法,因为到目前为止,在单击的ListView
排在的CheckBox
被选中或取消选中,变化被立即保存到数据库中。当行检查纱厂
是由可见的,但不是当行未选中可见。
所以,我没有设法找到解决办法的问题是,我不知道如何获得实际的微调
甚至获得列表项
一行被点击微调
是。在活动
扩展 ListActivity
。任何人都知道一种方法,我可以做到这一点,而无需使用 ViewHolder
或者我必须使用 ViewHolder
<?/ p >
下面是code,声明并填充的ListView
:
mSsCursor = mDbHelper.fetchAllSsPlaylistSs(mPlId);
startManagingCursor(mSsCursor); 的String [] =由新的String [] {pl_selected,BTDbAdapter.KEY_NAME,BTDbAdapter.KEY_NAME2}; INT []为= INT新[] {R.id.pl_selected,R.id.name,R.id.name2}; mAllSs =新SimpleCursorAdapter(这一点,R.layout.pl_edit_ss_row,mSsCursor,从,到);
mAllSs.setViewBinder(新SimpleCursorAdapter.ViewBinder(){
//设置值的自定义处理
公共布尔setViewValue(查看视图,光标光标,诠释参数:columnIndex){
如果(参数:columnIndex == 3){
连续的ViewGroup =(ViewGroup中)view.getParent()的getParent()。
MSID = cursor.getInt(0);
如果(cursor.getInt(3)大于0){
mCheckBox =(复选框)row.findViewById(R.id.pl_selected);
mCheckBox.setChecked(真);
mTSpin =(微调)row.findViewById(R.id.pl_t_spin);
mMSpin =(微调)row.findViewById(R.id.pl_m_spin);
mtvT =(TextView中)row.findViewById(R.id.pl_t);
MTVM =(TextView中)row.findViewById(R.id.pl_m);
mTSpin.setVisibility(View.VISIBLE);
mtvT.setVisibility(View.VISIBLE);
mMSpin.setVisibility(View.VISIBLE);
mtvM.setVisibility(View.VISIBLE);
//在T微调设置的值
PopulateTSpinner(cursor.getInt(4));
//在M微调设置的值
PopulateMSpinner(cursor.getInt(5));
}
其他{
mCheckBox =(复选框)row.findViewById(R.id.pl_selected);
mCheckBox.setChecked(假);
mTSpin =(微调)row.findViewById(R.id.pl_t_spin);
mMSpin =(微调)row.findViewById(R.id.pl_m_spin);
mtvT =(TextView中)row.findViewById(R.id.pl_t);
MTVM =(TextView中)row.findViewById(R.id.pl_m);
mTSpin.setVisibility(View.GONE);
mtvT.setVisibility(View.GONE);
mMSpin.setVisibility(View.GONE);
mtvM.setVisibility(View.GONE);
}
返回true;
}
返回false;
}
});
setListAdapter(mAllSs);
感谢。
我不知道如果我理解你的问题:如果你的程序流程是:
显示数据(名单
复选框
+的TextView
(纱厂
隐藏)) - >
用户点击一个行(纱厂
显示与(个体)的数据行) - >
用户选择那些东西纱厂
- >
保存在数据库中选择
块引用>那么我认为你应该用自定义适配器去照顾该行创立+数据绑定的自己(我不知道你将如何设置为
纱厂$ C $的监听器C>)。以下是你可能会怎么做这样的小例子(尽管可能不是$ P做的$ ptty方式):
公共类CustomAdapter扩展SimpleCursorAdapter { 私人LayoutInflater mInflater; 公共CustomAdapter(上下文的背景下,INT布局,光标C,
的String []从,INT []到){
超(背景下,布局,C,从,到);
mInflater = LayoutInflater.from(上下文);
} @覆盖
公共无效bindView(查看视图,上下文的背景下,光标光标){
ViewHolder支架=(ViewHolder)view.getTag(); //持有人
//模式
//设置TextView的文本的行
持有人名称
.setText(cursor.getString(cursor.getColumnIndex(名称)));
//将CheckBox的状态从数据库
INT状态= cursor.getInt(cursor.getColumnIndex(pl_selected));
//设置状态的CheckBox
holder.ckb.setChecked((状态&gt; 0)真:假的?);
//获取这个特殊行的id,我们将在以后的使用
//微调的听众
长theId = cursor.getLong(cursor.getColumnIndex(_ ID));
//看看它是否是时间显示纱厂
如果(状态&gt; 0){
//现在是时候展现纱厂。在这里,你会做的东西
//喜欢:设置Spinner的适配器+设置
//监听器
//我用的XML布局设置条目的微调(所以我
//选择的结果是一个字符串)
holder.spin1.setVisibility(View.VISIBLE);
holder.spin2.setVisibility(View.VISIBLE);
//设置theId作为一个标签,所以你知道哪些是微调采取行动
holder.spin1.setTag(新龙(theId));
holder.spin1
.setOnItemSelectedListener(新OnItemSelectedListener(){ @覆盖
公共无效onItemSelected(适配器视图&LT;&GT;母公司,
查看查看,INT位置,长的id){
龙realRowId =(长)parent.getTag();
// 我不知道
ContentValues CV =新ContentValues();
//我在这里保存了微调的列中选择
//项目被称为saved_item
cv.put(saved_item(字符串)父
.getItemAtPosition(位置));
// MDB是我的SQLiteDatabase实例
mDb.update(TBL,CV,_id =?,
新的String [] {字符串
.valueOf(realRowId)});
//我不知道你是怎么保存的数据中,
//以上只是一个例子
} @覆盖
公共无效onNothingSelected(适配器视图&LT;&GT;母公司){ }
});
//也实现了第二微调像第一个
}其他{
//需要prevent一个循环查看从造成损害
holder.spin1.setVisibility(View.GONE);
holder.spin2.setVisibility(View.GONE);
}
} @覆盖
公共查看NewView的(上下文的背景下,光标光标的ViewGroup父){
视图V = mInflater.inflate(R.layout.adapters_listspinner_row,
父母,假);
ViewHolder持有人=新ViewHolder();
holder.spin1 =(微调)v.findViewById(R.id.spinner1);
holder.spin1.setFocusable(假);
holder.spin2 =(微调)v.findViewById(R.id.spinner2);
holder.spin2.setFocusable(假);
holder.name =(TextView中)v.findViewById(R.id.textView1);
holder.ckb =(复选框)v.findViewById(R.id.checkBox1);
holder.ckb.setFocusable(假);
v.setTag(保持器);
返回伏;
} 类ViewHolder {
微调SPIN1,spin2;
TextView的名称;
复选框CKB;
} }此外,需要
onListItemcClick
方法:@覆盖
保护无效onListItemClick(ListView中升,视图V,INT位置,长的id){
//管理状态的CheckBox
复选框CKB =(复选框)v.findViewById(R.id.checkBox1);
ckb.setChecked(ckb.isChecked()!);
ContentValues CV =新ContentValues();
cv.put(pl_selected,ckb.isChecked()?1:0);
mDb.update(TBL,CV,_id =?,
新的String [] {将String.valueOf(ID)});
//重新查询所以变化是由适配器看到的数据库,这是可怕的!
游标重新= mDb.query(TBL,NULL,NULL,NULL,NULL,NULL,NULL);
mAllSs.changeCursor(重);
}作为一个建议,也许你可以修改你的应用程序的布局和移动
纱厂
出的ListView
一行。I have an issue with
Spinners
in aListView
. I have aListView
with aCheckBox
, a label, and twoSpinners
. TheSpinner
are populated from SQLite and that is working fine. I am not using theViewHolder
method because so far when theListView
row is clicked theCheckBoxes
are checked or unchecked and the change is immediately saved to the database. When the row is checked theSpinners
are made visible but are not visible when the row is not checked.So the issue that I haven't managed to find a solution for is that I have no idea how to get the actual
Spinner
or even get theListItem
row that the clickedSpinner
is on. TheActivity
extendsListActivity
. Anyone know a way I can do this without using aViewHolder
or do I have to use aViewHolder
?Here is the code that declares and populates the
ListView
:mSsCursor = mDbHelper.fetchAllSsPlaylistSs(mPlId); startManagingCursor(mSsCursor); String[] from = new String[]{"pl_selected", BTDbAdapter.KEY_NAME, BTDbAdapter.KEY_NAME2}; int[] to = new int[]{R.id.pl_selected, R.id.name, R.id.name2}; mAllSs = new SimpleCursorAdapter(this, R.layout.pl_edit_ss_row, mSsCursor, from, to); mAllSs.setViewBinder(new SimpleCursorAdapter.ViewBinder() { //custom handling of setting the value public boolean setViewValue(View view, Cursor cursor, int columnIndex) { if(columnIndex == 3) { ViewGroup row = (ViewGroup)view.getParent().getParent(); mSId = cursor.getInt(0); if (cursor.getInt(3) > 0) { mCheckBox = (CheckBox) row.findViewById(R.id.pl_selected); mCheckBox.setChecked(true); mTSpin = (Spinner) row.findViewById(R.id.pl_t_spin); mMSpin = (Spinner) row.findViewById(R.id.pl_m_spin); mtvT = (TextView) row.findViewById(R.id.pl_t); mtvM = (TextView) row.findViewById(R.id.pl_m); mTSpin.setVisibility(View.VISIBLE); mtvT.setVisibility(View.VISIBLE); mMSpin.setVisibility(View.VISIBLE); mtvM.setVisibility(View.VISIBLE); //set the values in the t spinner PopulateTSpinner(cursor.getInt(4)); //set the values in the m spinner PopulateMSpinner(cursor.getInt(5)); } else { mCheckBox = (CheckBox) row.findViewById(R.id.pl_selected); mCheckBox.setChecked(false); mTSpin = (Spinner) row.findViewById(R.id.pl_t_spin); mMSpin = (Spinner) row.findViewById(R.id.pl_m_spin); mtvT = (TextView) row.findViewById(R.id.pl_t); mtvM = (TextView) row.findViewById(R.id.pl_m); mTSpin.setVisibility(View.GONE); mtvT.setVisibility(View.GONE); mMSpin.setVisibility(View.GONE); mtvM.setVisibility(View.GONE); } return true; } return false; } }); setListAdapter(mAllSs);
Thanks.
解决方案I don't know if I understood your question: If your app flow is:
show a list of data(
CheckBox
+TextView
(Spinners
hidden)) ->
user clicks a row(theSpinners
appear for that row with(individual) data) ->
user selects something in thoseSpinners
-> save that selection in the databasethen I think you should go with a custom adapter and take care yourself of the row creation + data binding(I don't see how you would set a listener for the
Spinners
). Below is a small example on how you might do this(although probably not a pretty way of doing it):public class CustomAdapter extends SimpleCursorAdapter { private LayoutInflater mInflater; public CustomAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); mInflater = LayoutInflater.from(context); } @Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder holder = (ViewHolder) view.getTag(); // the holder // pattern // set the text for the TextView in your row holder.name .setText(cursor.getString(cursor.getColumnIndex("name"))); // status of the CheckBox from the database int status = cursor.getInt(cursor.getColumnIndex("pl_selected")); // set the CheckBox status holder.ckb.setChecked((status > 0) ? true : false); // get the id of this particular row, we'll use this later in the // Spinner's listeners long theId = cursor.getLong(cursor.getColumnIndex("_id")); // see if it is time to show the Spinners if (status > 0) { // it is time to show the Spinners. Here you would do stuff // like: setting up the Spinner's adapters + setting the // listener // I used a Spinner with entries set in the xml layout(so my // selection result is a String) holder.spin1.setVisibility(View.VISIBLE); holder.spin2.setVisibility(View.VISIBLE); // set theId as a tag so you know which Spinner was acted on holder.spin1.setTag(new Long(theId)); holder.spin1 .setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { Long realRowId = (Long) parent.getTag(); // I don't know ContentValues cv = new ContentValues(); // the column where I saved the spinner selected // item is called "saved_item" cv.put("saved_item", (String) parent .getItemAtPosition(position)); // mDb is my SQLiteDatabase instance mDb.update("tbl", cv, "_id = ?", new String[] { String .valueOf(realRowId) }); // I don't know how you saved the data, the // above is just an example } @Override public void onNothingSelected(AdapterView<?> parent) { } }); // also implement the second Spinner like the first one } else { // required to prevent a recycled View from causing damage holder.spin1.setVisibility(View.GONE); holder.spin2.setVisibility(View.GONE); } } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { View v = mInflater.inflate(R.layout.adapters_listspinner_row, parent, false); ViewHolder holder = new ViewHolder(); holder.spin1 = (Spinner) v.findViewById(R.id.spinner1); holder.spin1.setFocusable(false); holder.spin2 = (Spinner) v.findViewById(R.id.spinner2); holder.spin2.setFocusable(false); holder.name = (TextView) v.findViewById(R.id.textView1); holder.ckb = (CheckBox) v.findViewById(R.id.checkBox1); holder.ckb.setFocusable(false); v.setTag(holder); return v; } class ViewHolder { Spinner spin1, spin2; TextView name; CheckBox ckb; } }
Also, the required
onListItemcClick
method:@Override protected void onListItemClick(ListView l, View v, int position, long id) { // manage the CheckBox state CheckBox ckb = (CheckBox) v.findViewById(R.id.checkBox1); ckb.setChecked(!ckb.isChecked()); ContentValues cv = new ContentValues(); cv.put("pl_selected", ckb.isChecked() ? 1 : 0); mDb.update("tbl", cv, "_id = ?", new String[] { String.valueOf(id) }); // requery the database so the changes are seen by the adapter, this is horrible! Cursor re = mDb.query("tbl", null, null, null, null, null, null); mAllSs.changeCursor(re); }
As an advice, maybe you could modify the layout of your app and move the
Spinners
out of theListView
row.这篇关于在Android的ListView的纱厂,我必须用一个ViewHolder?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!