Search code examples
androidlistviewtwitter4j

Twitter4j set status to listview


I have a list called statusses and among it the text needed which are the tweets called status. I want to set the status to listview.

public class MainActivity extends Activity {

    ListView i;
    List<Status> statusess;
    ConfigurationBuilder cb;
    twitter4j.Status status3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        i = (ListView) findViewById(R.id.listView1);

        new LongOperation().execute("");

        }

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {

        TwitterFactory tf = new TwitterFactory(cb.build());
        Twitter twitter = tf.getInstance();

        String[] srch = new String[] {"Obama"};
        ResponseList<User> users = null;
        try {
            users = twitter.lookupUsers(srch);
        } catch (TwitterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for (User user : users) {
          System.out.println("Friend's Name " + user.getName()); // this print my friends name
              if (user.getStatus() != null) 
              {
              System.out.println("Friend timeline");
              try {
                statusess = twitter.getUserTimeline(user.getName());
            } catch (TwitterException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
              for (twitter4j.Status status3 : statusess) 
               {
                      System.out.println(status3.getText());
               }
              }
        }  


            return null;
    }        

    @Override
    protected void onPostExecute(String result) {    

    }

    @Override
    protected void onPreExecute() { 
    }

    @Override
    protected void onProgressUpdate(Void... values) {
    }
}

now this System.out.println(status3.getText()); works 100%, the tweets are showing in the console. but how do I get them to the listview in onPostExecute?

I tried

i.setAdapter(new ArrayAdapter<twitter4j.Status>(MainActivity.this,
        android.R.layout.simple_list_item_1, statusess));

But I get a lot of text not needed, I need only status3 which is text(tweet), this displays a lot of stuff like tweet id, retweet, followers, etc ..

I also tried this

@Override
protected void onPostExecute(String result) {    
    for (twitter4j.Status status3 : statusess) 
    {
    i.setAdapter(new ArrayAdapter<statusess>(MainActivity.this,
            android.R.layout.simple_list_item_1, status3.getText()));
    }
}

but didn't work, a lot of red line xD


Solution

  • users = twitter.lookupUsers(srch);
    

    This gives you a list of users. You are running a for-loop to iterate through the list, changing statuses on each iteration. When the for-loop ends, statuses holds the status list(returned by twitter.getUserTimeline(user.getName())) of the last user. Is this really what you want?

    For example, you can display the user list that is returned using twitter.lookupUsers(srch), in the ListView. And, on a item click event, display the status list for that user.

    Once you decide on the user for whom you need the status list, do the following:

    // Declare an ArrayList with class scope
    ArrayList<String> statusListTextOnly;
    
    // Initialize it in doInBackground()
    @Override
    protected String doInBackground(String... params) {
        ....
        ....
        statusListTextOnly = new ArrayList<String>();
    
        // Initialize 'statuses' for the user that you have decided on
        statusess = twitter.getUserTimeline(user.getName());
    
        // Run a for-loop to fill 'statusListTextOnly'
        // We will use 'statusListTextOnly' with the ArrayAdapter
        for (twitter4j.Status status3 : statusess) {
            statusListTextOnly.add(status3.getText());
        }
    }
    
    // Initialize/reset ArrayAdapter
    @Override
    protected void onPostExecute(String result) {
        i.setAdapter(new ArrayAdapter<String>(MainActivity.this,
        android.R.layout.simple_list_item_1, statusListTextOnly));
    }
    

    The problem with your code lies here:

    i.setAdapter(new ArrayAdapter<twitter4j.Status>(MainActivity.this,
        android.R.layout.simple_list_item_1, statusess));
    

    Objects passed to an ArrayAdapter are displayed using the toString() method. Now, toString() is mostly overriden for custom objects and serves the purpose of providing a meaningful description of the object itself. It can be overriden to provide literally any kind of information in a String format. In case of Status objects, toString() returns a bit more than what you need. So, we extract the relevant info using Status#getText() and store it in a separate ArrayList.

    Your second attempt has problems as well:

    @Override
    protected void onPostExecute(String result) {    
        for (twitter4j.Status status3 : statusess) {
            i.setAdapter(new ArrayAdapter<statusess>(MainActivity.this,
                android.R.layout.simple_list_item_1, status3.getText()));
        }
    }
    

    Here, you are setting the generic parameter of ArrayAdapter to a variable('statuses'): the generic parameter should be a class. Next, you pass a String as the last argument, whereas an ArrayAdapter's constructor can either take an array of objects, or an ArrayList. Third, you are creating a new instance of your ArrayAdapter and setting it to the ListView on each iteration of the for-loop. This is logically incorrect. You need one instance of an ArrayAdapter and you only need to set it once.

    What else can you do:

    • Create a custom ArrayAdapter that affords new functionality, for example: showing of images along with text.

    • Dig into BaseAdapter: Highly customizable, all-purpose adapter.