I wanna add items to my list but it only shows the first one:
public class MainActivity extends Activity {
Server server;
TextView infoip, msg;
TextView usersTitle;
String[] array = {"a"};
ArrayList<String> lst;
ArrayAdapter<String> adapter;
ListView userList;
#Override
public void onCreate(Bundle savedInstanceState) {
lst = new ArrayList<String>(Arrays.asList(array));
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, lst);
userList = (ListView) findViewById(R.id.userList);
userList.setAdapter(adapter);
From this other class method, everytime it is called I want the text to go below the first one. The method certainly runs but it does not put the text below the previous one. It just shows "a"! Anyone knows why?
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.lst.add(message);
activity.adapter.notifyDataSetChanged();
}
});
I have also tried:
adapter.insert(String, int);
lst.add(int, String);
And even added in the onCreate method this:
lst.add(1, "2");
adapter.notifyDataSetChanged();
And still doesnt add the "2"!!
If you are adding items to Arraylist from another class ,you have to declare your Arraylist Static.So that it can hold items in memory.
Replace ArrayList lst with public static ArrayList
Here is the solution to your Problem.I have created an Activity class and Tests java class.
public class MainActivity extends Activity {
String[] array = {"a"};
public static ArrayList<String> lst;
ArrayAdapter<String> adapter;
ListView userList;
Tests tests = new Tests();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userList = (ListView) findViewById(R.id.userList);
lst = new ArrayList<String>(Arrays.asList(array));
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, lst);
userList.setAdapter(adapter);
tests.callThread();
}
}
Here is the Tests.java Class
public class Tests {
int i = 0;
String message = "";
Thread runOnUiThread;
public void callThread()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
while (i < 10) {
i = i + 1;
message = String.valueOf(i);
//Create a server socket object and bind it to a port
MainActivity.lst.add(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}
Just call your service inside this thread where I have incremented variable i and by this way you can populate the list in right order.
Can you tell whether the other class is Activity or Fragment ?
And while adding the data into Arraylist, you don't need the Thread to be run in order to insert new data to Arraylist
Try to make "lst" and "adapter" both static.
I'm suspicious about the runOnUiThread. Can you provide more information why did you use this function? Also i highly recommend using RecyclerView
Also you can refer to this post for adding items to RecyclerView
Related
I d like to make a while(true) in my code but ,when i run, i don t see anything:
I've tried with AsyncTask but i think that a infinite loop it's too heavy.
public class openActivity extends AppCompatActivity {
ArrayList<String> myArraylist = new Arraylist<> ();
CustomAdapter myAdapter;
ListView list;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.myActivity);
list = findViewById(R.id.myList);
try {
while (true) {
Document doc = Jsoup.connect(myUrl).get;
//here i get info i need
//add that info to myArraylist
myAdapter = new CustomAdapter(this, myArraylist);
list.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
while (myArrayList.get(0).equals(myArraylist.get(0))) {
Thread.sleep(900000);
}
}
} catch (Exception ex) {
ex.getLocalizeMessage()
}
}
Your loop is blocking the UI thread. To perform a periodic task you should use a ScheduledExecutorService.
Also, avoid recreating the adapter on every iteration. Update the existing data and use DiffUtils to notify the changes.
or you can try this :
myAdapter = new CustomAdapter(this, myArraylist);
list.setAdapter(myAdapter);
getData();
public void getData(){
Document doc = Jsoup.connect(myUrl).get;
//here i get info i need
//add that info to myArraylist
myAdapter.notifyDataSetChanged();
getData()
}
Initially, after setting up custom listview, no more items are getting added i.e displayed in list view inspite of adding Object item from FirebaseMessagingService.
I have declared listView static so that Object can be added to the list from other classes or services.
Here's my code:
FirebaseMessagingService:
#Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
//Toast.makeText(getApplicationContext(), remoteMessage.getData().get("transaction"),Toast.LENGTH_SHORT).show();
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
Gson gson = new Gson();
Block b = gson.fromJson(remoteMessage.getData().get("transaction"), Block.class);
OpenChain.arrayList.add(b);
}
});
}
ListView activity code:
public static ArrayList<Block> arrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open_chain);
arrayList = new ArrayList<>();
getSupportActionBar().setTitle("Vote Ledger");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ListView listView = (ListView) findViewById(R.id.listView);
BlockchainAdap adap = new BlockchainAdap(this, arrayList);
listView.setAdapter(adap);
adap.notifyDataSetChanged();
}
**I am receiving object from cloud in json format
**Also able to add objects from within listview activity but not from FirebaseMessagingSerivce
I have declared listView static so that Object can be added to the
list from other classes or services.
Not, a good solution, you are leaking arrayList here, as it wont be garbage collected when activity gets destroyed.
A better approach would be to use LocalBroadCast in this scenario.
Checkout the link for info
https://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
Now, what you are doing wrong. You, are modifying the arraylist but you are not notifying the adapter about the same.
Try this..
private ArrayList<Block> arrayList = new ArrayList<>();
private BlockchainAdap adap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open_chain);
getSupportActionBar().setTitle("Vote Ledger");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ListView listView = (ListView) findViewById(R.id.listView);
adap = new BlockchainAdap(this, arrayList);
listView.setAdapter(adap);
}
public static void updateList(Block b){
arrayList.add(b);
adap.swap(arrayList);
}
In FirebaseMessagingService
#Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
Gson gson = new Gson();
Block b = gson.fromJson(remoteMessage.getData().get("transaction"), Block.class);
OpenChain.updateList(b);
}
Also, expose a method in your ** BlockchainAdap** for swap.
class BlockchainAdap {
ArrayList<Block> arrayList;
BlockchainAdap(ArrayList<Block> arrayList){
this.arrayList = arrayList;
}
public void swap(ArrayList<Block> arrayList){
this.arrayList = arrayList;
notifydatasetChanged();
}
// other methods
}
This will work, but use
LocalBroadcastReceiver from messaging service to OpenChain activity.
Use RecyclerView instead of ListView.
In Meteor on to get list from server onDataAdded override method calls again until list end so in that if I pass array value to adapter it will call again and again.
My code:
#Override
public void onDataAdded(String s, String s1, String s2) {
Log.d("onDataAdded",""+s);
//lists is collection name
if(s.contains("lists")) {
arrayList.add(s1)
adapter= new customAdapter(this,arrayList);
list.setAdapter(adapter)
}
}
If I am calling :
adapter= new customAdapter(this,arrayList);
list.setAdapter(adapter)
onDataAdded method of Meteor adapter is setting again and again until its reach last value is there any way to set adapter once by getting size or any another way please suggest.
You should set the adapter once inside onCreate method and then use notifyDataSetChanged method to notify the adapter about any changes in the dataset.
ArrayList<String> arrayList = new ArrayList<String>();
CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
adapter = new CustomAdapter(this, arrayList);
list.setAdapter(adapter);
}
#Override
public void onDataAdded(String s, String s1, String s2) {
Log.d("onDataAdded",""+s);
//lists is collection name
if(s.contains("lists")) {
arrayList.add(s1);
// notify the adapter
adapter.notifyDataSetChanged();
}
}
I want to declare arrayList into this line:
public class tlcity extends Activity {
//ArrayList<String> idArray = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
and into the other method,for example this method:
protected void onPostExecute(String result) {
//fill the arraylist
...
and into the other method for example this method read arraylist data:
public void readlist(){
//read the arraylist data and show
}
How can i do this?
You can declare ArrayList like this
ArrayList<String> list;
list = new ArrayList<String>();
You can add, remove items in ArrayList Like this
list.add("A");
list.remove(0);
ArrayList<String> abc=new ArrayList<String>();
You can initialize or create an instance of your array list like this
idArray = new ArrayList();
You can perform any operations to it using idArray object.
For example you can add items like this
idArray.add("item1");//In you case its a list of strings.
In the same way you would do that in another Java app / class:
public class tlcity extends Activity {
List<String> idArray;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
idArray = new ArrayList<String>();
}
protected void onPostExecute(String result) {
idArray.add("One");
idArray.add("Two");
idArray.add("Three");
...
}
public void readlist(){
for (final String element : idArray) {
// Use the nth string
}
}
I want to declare arrayList into this line:
ArrayList<String> myList;
and into the other method,for example this method:
myList = new ArrayList<String>;
and into the other method for example this method read arraylist data:
for(int i=0; i<myList.size(); i++)
System.out.println(myList.get(i).toString());
If you want to use ArrayList locally then declare it locally. if you want to use it in all methods then declare it globally in class.
public class tlcity extends Activity {
ArrayList<String> idArray = new ArrayList<>(); // to Use this arraylist globally.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<String> localaraaylist = new ArrayList<>(); //to use arraylist in only in oncreate method.
....
According to your post, telling how to declae ArrayList will not enough as you have some methods like onPreExecute() which is a method ofAsyncTask Interface.
Look at this,
public class MainActivity extends ActionBarActivity {
ArrayList<String> arrayList; // declaring ArrayList here
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrayList = new ArrayList<String>(); // Initializing arrayList
arrayList.add("initial text"); // adding a data to arrayList
ListView listView = (ListView)findViewById(R.id.listView);
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,arrayList); // setting the arrayList in ArrayAdapter
listView.setAdapter(adapter);
new LongOperation().execute(); // async Task
}
private class LongOperation extends AsyncTask<Void, Void, Void> {
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
// progress dialog starts here
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Loading...");
progressDialog.show();
}
#Override
protected Void doInBackground(Void... voids) {
// for understanding purpose, i made a thread to sleep for 5 sec and later it will add A,B & C to ArrayList.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// adding few more items to arrayList
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss(); // dismissing the progress Dialog
adapter.notifyDataSetChanged(); // refreshing listview
readA(); // read the arrayList
}
}
public void readA()
{
for (int i = 0; i<arrayList.size(); i++)
{
Log.d("key",arrayList.get(i));
}
}
}
Output :
If you run the above code, Initially your list view will only contain only one item & after 5 sec loading it will add another 3 items. The below information will print in logcat that reads the ArrayList.
04-13 14:07:32.395 1123-1123/? D/key﹕ initial text
04-13 14:07:32.395 1123-1123/? D/key﹕ A
04-13 14:07:32.395 1123-1123/? D/key﹕ B
04-13 14:07:32.395 1123-1123/? D/key﹕ C
I'm using SherlockListFragment(whichis the same as ListFragment) for displaying sms conversation list
Here is the code
public static class TitlesFragment extends SherlockListFragment
{
static ConversationAdapter adapter;
static List<String> msgList;
static Activity activity;
static ListView listView;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DataGetters dataGetters = new DataGetters();
activity = getActivity();
msgList = dataGetters.getCONVERSATIONS(activity.getApplicationContext());
adapter = new ConversationAdapter(activity, msgList);
setListAdapter(adapter);
}
Code above prints all current sms conversations
like this:
I'm refreshing adapter from code below by calling adapter.notifyDataSetChanged(); witch is called when new sms is received
public class ReceiverClass extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
Thread.sleep(2000);
return null;
}
#Override
protected void onPostExecute(String result) {
TitlesFragment.adapter.notifyDataSetChanged();
}
But fallowing code overides existing list view items insted of adding new list item position like this:
When i activity is recreated i get what i want but only then: example:
You are most likely incorrectly modifying the List that the ListAdapter is attached to.
So the problem was not me not modifiy adpater list with new position
Here is the code that neded to be added
msgList= dataGetters.getCONVERSATIONS(activity.getApplicationContext());
ConversationAdapter.msgList = msgList;
TitlesFragment.adapter.notifyDataSetChanged();
Solved thanks to Mark Nguyen