5

I want to update a single row in my listview with different content once i press a button. I know i can use notifydatasetchanged() but that would update the whole listView.

I have read this answer and it fits perfectly for what I want to do.

I have done a listview with 5 rows and when I press the button I want to update the 4th row with a different text. I dont want to set the text programatically since this is just a dummy project just to see if refreshing a single row is possible and my real project is much more complex than just a textview.

So my question is: can i use getView() to update a single row in a listview?

Here is my code:

my Activity:

public class MainActivity extends Activity {

    public ListView list1;
    public listAdapter adapter;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list1 = (ListView) findViewById(R.id.my_list);
        adapter = new listAdapter(this);
        list1.setAdapter(adapter);

        Button button1 = (Button) findViewById(R.id.my_button);
        button1.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                adapter.setText("Different text");
                View row2Update = list1.getChildAt(3);
                list1.getAdapter().getView(3, row2Update, list1);

            }
        });

    } 

}

My adapter :

public class listAdapter extends BaseAdapter{

    public Activity activity;
    public String text="Normal Text";

    public listAdapter(Activity activity){

        this.activity = activity;
    }

    public void setText(String text){
        this.text = text;
    }

    public int getCount() {
        return 5;
    }

    public Object getItem(int position) {

        return null;
    }

    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = activity.getLayoutInflater();
        LinearLayout rowView = (LinearLayout) inflater.inflate(R.layout.row_layout, null);
        TextView textView = (TextView) rowView.findViewById(R.id.row_text);
        textView.setText(text);
        return rowView;
    }

}

This is what the activity looks like:

Activity snapshot

But when I press my button nothing changes

Community
  • 1
  • 1
BigBen3216
  • 868
  • 1
  • 8
  • 23

1 Answers1

3

You cannot call the getView() method of the adapter yourself. The adapter's getView() method is is only called, when

  • The listview is create
  • when the user scrolls the list view
  • when notifysetdatachanged() is called.
    All these are done by the OS. GetView() is called for all the rows in the listview. It is not called for just a single row. So, if you want to change the rows, you have to provide the data again in a String[], ArrayList<> etc
    If you want different text to appear for for a single row, onClick() of a button - you can do this

    public class listAdapter extends BaseAdapter{

    public Activity activity;
    public ArrayList<String> text;
    
    public listAdapter(Activity activity){
    
        this.activity = activity;
    }
    
    public void setText(ArrayList<String> text){
        this.text = text;
    }
    
    public int getCount() {
        return 5;
    }
    
    public Object getItem(int position) {
    
        return null;
    }
    
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }
    
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = activity.getLayoutInflater();
        LinearLayout rowView = (LinearLayout) inflater.inflate(R.layout.row_layout, null);
        TextView textView = (TextView) rowView.findViewById(R.id.row_text);
        textView.setText(text[position]);
        return rowView;
    }
    

    }
    And in your Activity :

    list1 = (ListView) findViewById(R.id.my_list);
    adapter = new listAdapter(this);
    String[] entries={"Normal Text","Normal Text","Normal Text","Normal text","Normal text"};
    ArrayList<String> text=Arrays.asList(entries);
    adapter.setText(text);
    list1.setAdapter(adapter);
    
    Button button1 = (Button) findViewById(R.id.my_button);
    button1.setOnClickListener(new OnClickListener() {
    
        public void onClick(View v) {
           text.set(3,"Different Text");
            adapter.setText(text);
            list1.setAdapter(adapter);
    
        }
    });
    


    There is another way of doing it also as @Andy suggested in one of the comments :

    listViewPeople.setOnItemClickListener(new ListView.OnItemClickListener() {
            @Override
        public void onItemClick(AdapterView<?> a, View v, int position, long l) {
                 //IF YOU WANT TO CHANGE THE CONTENT OF THE ROW CLICKED
           if(position == someNumber) {
                   text.set(position,"different Text");
                   list1.setAdapter(text);
           }
        }
    });
    

Sorry for the bold text. For some reason the CTRL+K is not working for the above code.

Ashwin
  • 12,691
  • 31
  • 118
  • 190
  • Great answer. I agree with you. Another thing he could do is just set onItemClickListener to the ListView itself, and if the position is whatever (assuming you don't use a button), you just update the list in the adapter. Of course ultimately he needs to figure out which option is best for him. – Andy Nov 11 '12 at 03:20
  • @Andy : You are right. Actually that would be better Idea. But since, he specifically asked to change the row content on click of a button, I went for this. – Ashwin Nov 11 '12 at 03:30
  • :) Oh no, you are technically right @Ashwin just because its more efficient. There isn't any unnecessary work being done. Since he only wants to update a single line. But he does mention that this is only a test, so I figure he should also have another method incase he wants more to be updated. – Andy Nov 11 '12 at 03:35
  • @Andy : okay. I will put it up:) – Ashwin Nov 11 '12 at 03:41
  • yeah I though i could use the getView() method in my activity and it would be the same as if i performed a scroll, but I guess the only way to achieve a single row update is to set the content of the row manually as you suggest – BigBen3216 Nov 11 '12 at 06:39
  • @BigBen3216 : yeah...you can go through the source code of listview.setAdapter(), to see if there is any workaround- http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/ListView.java#ListView.setAdapter%28android.widget.ListAdapter%29 .Do tell me if you find out something. – Ashwin Nov 11 '12 at 06:59