Keep textview content in listview scrolling

*爱你&永不变心* 提交于 2019-12-11 19:44:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!