问题
I have read about this confusing material, "listview scrolling lost content" and It made me frustrated. So I decide to ask here. Here is what I need:
(TextItems) (TextValue)
Item1 0
Item2 0
Item3 0
// after input custom edittext dialog, It must be:
Item1 3
Item2 8
Item3 5
But, after I scroll down my screen(3 items isnot displayed on screen) then sroll up again, those item values is back to 0. Here is my Main.java:
String[] items = {"Item1","Item2","Item3","Item4",..,"Item30"};
final ListView listView = (ListView)findViewById(R.id.listItems);
ArrayAdapter<String> adapter = new LVAdapter(this, items);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
AlertDialog.Builder alert = new AlertDialog.Builder(Main.this);
LayoutInflater inflater = Main.this.getLayoutInflater();
View v = inflater.inflate(R.layout.input_dialog, null);
alert.setView(v);
final EditText userInput = (EditText)v.findViewById(R.id.editInput);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
TextView tv = (TextView)view.findViewById(R.id.textValue); // for giving value on each Items
tv.setText(userInput.getText());
}
});
AlertDialog al = alert.create();
al.show();
}
});
Then, its my LVAdapter.java
public class LVAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] val;
public LVAdapter(Context context, String[] val) {
super(context, R.layout.detail_item, val);
this.context = context;
this.val = val;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.detail_item, parent, false);
TextView tv = (TextView)v.findViewById(R.id.textItems); //for storing Item1, Item2, .., etc.
tv.setText(val[position]);
return v;
}
Main.xml
<ListView
android:id="@+id/listItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="afterDescendants" >
</ListView>
And Its main_items.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textItems"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:text="TextView"
android:layout_alignParentLeft="true"
android:padding="5dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<!-- I need to set this textView based on users input -->
<TextView
android:id="@+id/textValue"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_alignParentRight="true"
android:text="0"
android:padding="5dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
Here I am. Stack in how to implement "what is it called" for keeping my value, even I srolling my screen. Thanks in advance.
回答1:
You need to set entered value to list or array you passed to your adapter.
Like this :
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
AlertDialog.Builder alert = new AlertDialog.Builder(Main.this);
LayoutInflater inflater = Main.this.getLayoutInflater();
View v = inflater.inflate(R.layout.input_dialog, null);
alert.setView(v);
final EditText userInput = (EditText)v.findViewById(R.id.editInput);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Don't set text view item here
// Here you need to set value to your array or list which you passed to adapter for listview
items[position] = userInput.getText().toString();
adapter.notifyDataSetChanged(); // Use this for reflects the entered value
}
});
AlertDialog al = alert.create();
al.show();
}
});
回答2:
ListView is recycling its child views and does not save your input automatically. This means that you have to do the dirty work yourself. First save the input and then retrieve it and display it in the correct place. There are some answers on stack you can check out but anyway here is a code I used:
public class ArrayListAdapter extends BaseAdapter{
ArrayList<Product> productlist= null;
private Activity context=null;
public ArrayListAdapter(Activity context, ArrayList<Product> objects) {
this.productlist= objects;
this.context=context;
}
static class ViewHolder{
TextView textvw;
EditText edittx;
int ref;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
if(productlist!=null&&productlist.size()>0)
return productlist.size();
return 1;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return productlist.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder holder;
if (convertView==null){
holder= new ViewHolder();
LayoutInflater inflater = context.getLayoutInflater();
convertView=inflater.inflate(R.layout.list_item, null);
holder.textvw =(TextView)convertView.findViewById(R.id.name);
holder.edittx =(EditText)convertView.findViewById(R.id.quantity);
convertView.setTag(holder);
}else
{
holder=(ViewHolder)convertView.getTag();
}
holder.ref=position;
holder.textvw.setText(productlist.get(position).name);
holder.edittx.setText(productlist.get(position).quantity);
holder.edittx.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
productlist.get(holder.ref).quantity= s.toString();
productlist.get(holder.ref).quantity);
productlist.get(holder.ref+1).quantity );
}
});
return convertView;
}
}
回答3:
Error is in your getView method. You need to modify your getView like this
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null){
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.detail_item, parent, false);
holder. tv = (TextView)v.findViewById(R.id.textItems);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder. tv.setText(val[position]);
return v;
}
Also add holder class
class ViewHolder {
TextView tv;
}
回答4:
Create a Hashmap of views and add your listview item views in it, and on scrolling if your item is already present in hashmap then retrieve that item from hashmap. This will not result in your content lost.
HashMap<Integer, View> hashMap = new HashMap<Integer, View>();
public View getView(final int position, View view, ViewGroup parent)
{
final ViewHolder holder;
if (hashMap.containsKey(position)) {
return hashMap.get(position);
}
holder = new ViewHolder();
view = inflater.inflate(R.layout.detail_item, null);
// set tag and put views in hashmap
view.setTag(holder);
hashMap.put(position, view);
return view;
}
Hope this will work...... Thank You
来源:https://stackoverflow.com/questions/31934216/keep-textview-content-in-listview-scrolling