ArrayAdapter does not update view when notifyDataSetChanged() is called - android

So I have a piece of code that look like this
floorList = new ArrayList<String>();
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, floorList);
arrayAdapter.setNotifyOnChange(true);
floorSpinner.setAdapter(arrayAdapter);
floorList.add("a");
Call<ParkourResponse<ParkingPlaceResponseObject>> getPlaceDetailCall = Helper.getParkourService().getPlaceDetail(placeID);
getPlaceDetailCall.enqueue(new Callback<ParkourResponse<ParkingPlaceResponseObject>>() {
#Override
public void onResponse(Call<ParkourResponse<ParkingPlaceResponseObject>> call, Response<ParkourResponse<ParkingPlaceResponseObject>> response) {
ParkingPlaceResponseObject placeDetail = response.body().getRespObject();
Floor[] floorArray = placeDetail.getFloor();
floorList.clear();
arrayAdapter.notifyDataSetChanged();
for(int i = 0; i < floorArray.length; i++){
floorList.add(Integer.toString(floorArray[i].getNumber()));
}
}
#Override
public void onFailure(Call<ParkourResponse<ParkingPlaceResponseObject>> call, Throwable t) {
}
});
So when I tried to add "a" that is not part of the Retrofit service, the spinner is updated.
But everything that I do to floorList inside the onResponse() does not update the adapter and spinner.
I tried to clear it on the onResponse() and then call the notifyDataSetChanged(), even that does not delete the "a" option from the spinner.
Anyone know how to fix this?

Note the comments by Selvin and Gautam while following this answer, as they are correct and will help you to understand why the code should look like the following:
floorList = new ArrayList<String>();
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, floorList);
arrayAdapter.setNotifyOnChange(true);
floorSpinner.setAdapter(arrayAdapter);
arrayAdapter.add("a"); //I would jsut pass this into the adapter's constructor
Call<ParkourResponse<ParkingPlaceResponseObject>> getPlaceDetailCall = Helper.getParkourService().getPlaceDetail(placeID);
getPlaceDetailCall.enqueue(new Callback<ParkourResponse<ParkingPlaceResponseObject>>() {
#Override
public void onResponse(Call<ParkourResponse<ParkingPlaceResponseObject>> call, Response<ParkourResponse<ParkingPlaceResponseObject>> response) {
ParkingPlaceResponseObject placeDetail = response.body().getRespObject();
Floor[] floorArray = placeDetail.getFloor();
arrayAdapter.clear(); //update the adapter, not the external list
arrayAdapter.setNotifyOnChange(false); //we'll only update after list is full, for efficiency
for(int i = 0; i < floorArray.length; i++){
arrayAdapter.add(Integer.toString(floorArray[i].getNumber()));
}
arrayAdapter.setNotifyOnChange(true);
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<ParkourResponse<ParkingPlaceResponseObject>> call, Throwable t) {
}
});

Related

How to stop refreshing recyclerview data scroll to top position android everytime

I am trying to make a layout with recyclerview something like the video. I made a recyclerview which update list after certain interval but the problem is after data update it scroll to top position automatically. I want to make something like the video. https://youtu.be/omcS-6LeKoo
I have tried with link from SO
RecyclerView scrolls to top position when change the adapter data RecyclerView notifyDataSetChanged scrolls to top position but unable to solve. below is my attempt
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show();
listShow();
handler.postDelayed(this,1000);
}
},1000);
}
void listShow(){
retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class);
Call<ModelClass_JSONParse> getDetails = retrofitApiCall;
anime = ExtendedAnime.getAll();
getDetails.enqueue(new Callback<ModelClass_JSONParse>() {
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
list.add(mModelClass_adapter);
}
adapter = new Adapter(getApplicationContext(),list);
StaggeredGridLayoutManager layoutManager = new
StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<ModelClass_JSONParse> call, Throwable t) {
Log.v("Res",call.toString());
}
});
}
These lines of code are causing the problem for you. You're setting a new adapter reference and linear layout manager reference every time of your API calling.
adapter = new Adapter(getApplicationContext(),list);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
To Do your desired task you need to do following steps -
Just set your LayoutManager and adapter for the first time.
Make a setDataList method in your adapter class. And set your updated list to adapter list.
And then every time of calling API set that list to setDataList and call adapter.notifyDataSetChanged() method of your adapter class.
The above steps will solve your problem. Just give it a try.
The problem is probably because of you are setting new adapter reference in network callback method onResponse(). Try setting adapter in onCreate and then update dataset in callback.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
recyclerView.setAdapter(yourAdapter);
}
In network callback,
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
adapter.setDataSet(newDataList) //not change adapter reference,only update data set
}
}
Implement setDataSet() method in your adapter to update list like below.
class YourAdapter extends RecyclerView.Adapter<>{
priavate List<> list = new ArrayList();
public void setDataSet(newList:List<>){
list.clear();
list.addAll(newList);
notifyDataSetChanged();
}
}
Don't use adapter.notifyDataSetChanged(); method because I think your main view must be wrap content so either set a fixed height like 150dp.
Try different methods like notifyItemChanged(), notifyItemRangeChanged(), notifyItemInserted()
You are setting adapter again and again when the response is changing, so you should change list and set adapter in onCreate.
Arraylist<ModelClass_adapter> list = new Arraylist<ModelClass_adapter>;
Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
//set adapter here
adapter = new Adapter(getApplicationContext(),list);
StaggeredGridLayoutManager layoutManager = new
StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show();
listShow();
handler.postDelayed(this,1000);
}
},1000);
}
void listShow(){
retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class);
Call<ModelClass_JSONParse> getDetails = retrofitApiCall;
anime = ExtendedAnime.getAll();
getDetails.enqueue(new Callback<ModelClass_JSONParse>() {
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
list.clear();
list.add(mModelClass_adapter);
}
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<CurrencyModelClass_JSONParse> call, Throwable t) {
Log.v("Res",call.toString());
}
});
}
You are setting a new adapter every time and a new layout manager response comes.
which may cause this type of problem. you need to set adapter and layout manager in onCreate. just update adapter list in response of the api.
according to this answer you need linear layout manager only.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
list= ArrayList<>();
adapter = new Adapter(getApplicationContext(),list);
LinearLayoutManager linearLayoutManager = new
LinearLayoutManager(context, OrientationHelper.VERTICAL, false);
recycleView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show();
listShow();
handler.postDelayed(this,1000);
}
},1000);
}
void listShow(){
retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class);
Call<ModelClass_JSONParse> getDetails = retrofitApiCall;
anime = ExtendedAnime.getAll();
getDetails.enqueue(new Callback<ModelClass_JSONParse>() {
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
adapter.getList().add(mModelClass_adapter);
}
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<CurrencyModelClass_JSONParse> call, Throwable t) {
Log.v("Res",call.toString());
}
});
}
you can do by following way
First get the count of your current datalist
int position = datalist.size();
after adding data into datalist
call DataAdapter.notifyDataSetChanged();
then move cursor to position in recyclerview
recyclerView.scrollToPosition(position);
Happy coding...!

Adding Edit and Delete buttons in each row in listview in android

Hi in the below code we had created a listview .In the Screen contains one add button .If we press the button data will send as json request and get the response from the server.
If the response is successfull then I am adding each row add and delete button for each row.
can any one help me where i did the mistake
public class AddBuildingFragement extends Fragment {
EditText et_building;
TextView Add,mTitle,delete;
ListView lv;
String name;
ArrayList<String> arrayList;
ArrayAdapter<String> adapter;
public AddBuildingFragement() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//((NavigationViewActivity) getActivity ( )).setActionBarTitle ("LIGHT CONTROL");
View rootView = inflater.inflate(R.layout.activity_building, container, false);
init(rootView);
return rootView;
}
private void clickListener() {
Add.setOnClickListener (new View.OnClickListener ( ) {
#Override
public void onClick(View v) {
name=et_building.getText ().toString ();
String level="1";
// final ProgressDialog progressDialog = new ProgressDialog(getActivity ());
// progressDialog.setIndeterminate(true);
// progressDialog.setMessage("Authenticating...");
// progressDialog.setCanceledOnTouchOutside(false);
// progressDialog.setCancelable(false);
// progressDialog.show();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API.URL_BASE)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
API service = retrofit.create(API.class);
try{
JSONObject parmobject=new JSONObject ();
parmobject.put("name",name);
parmobject.put("level",level);
Call <NewBuilding> userCall = service.getbuildinglist (parmobject.toString());
userCall.enqueue(new Callback <NewBuilding> () {
#Override
public void onResponse(Call<NewBuilding> call, Response <NewBuilding> response) {
// if (progressDialog != null)
// progressDialog.dismiss();
Integer response1= response.code();
Log.d ("response", String.valueOf (response1));
if (response !=null && response.isSuccessful()&&response.code()==200) {
String status=response.body ().getStatus ();
if(status.equalsIgnoreCase ("success")){
makeText(getActivity (), "Building successfully Added", Toast.LENGTH_SHORT).show();
arrayList.add (name);
adapter.notifyDataSetChanged ();
}
} else {
makeText(getActivity (), "Invalid EmailId and password", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<NewBuilding> call, Throwable t) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
private void init(View rootView) {
et_building=(EditText)rootView.findViewById (R.id.build_name);
Add=(TextView)rootView.findViewById (R.id.addbuild);
//delete=(TextView)rootView.findViewById (R.id.delete_item);
lv=(ListView)rootView.findViewById (R.id.list_building);
arrayList=new ArrayList<String> ();
adapter=new ArrayAdapter<String> (getActivity (),R.layout.building_listview_item,arrayList);
MyCustomAdapter adapter = new MyCustomAdapter(arrayList, this);
//handle listview and assign adapter
//ListView lView = (ListView)findViewById(R.id.my_listview);
//lView.setAdapter(adapter);
lv.setAdapter(adapter);
clickListener();
}
I guess the problem is coming from adapter.notifyDataSetChanged() as it is not working. Here :-
if(status.equalsIgnoreCase ("success")){
makeText(getActivity (), "Building successfully Added", Toast.LENGTH_SHORT).show();
arrayList.add (name);
adapter.notifyDataSetChanged ();
}
Possible Fix #1 : Clone the base method in your Adapter class as :
public void notifyDataSetChangedCustom(List<String> newdata) {
mData.clear();
mData.addAll(newdata);
this.notifyDataSetChanged();
}
And call adapter.notifyDataSetChangedCustom(newdata) instead of adapter.notifyDataSetChanged
Possible Fix #2 : If still, it doesn't work, stop using only notifyDataSetChanged. Instead, try re-initializing the adapter & then call notifyDataSetChanged.
AttendanceAdapter adapter = new AttendanceAdapter(this, attendanceItems);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
Possible Fix #3: You're getting a null response from Retrofit. I think there might be 3 causes,
Target Server is not responding
You forgot to add Internet Permission.
The Invisible Killer ClearTextTraffic introduced on Android Pie : Fix by adding android:usesCleartextTraffic="true" to your <application> tag in AndroidManifest.xml
Hope it will help you.

Is it an issue to use "setAdapter()" more than once in recyclerview?

Actually I am fetching data from server and showing that on my recyclerview .But it was showing nothing . Even after a lot of question's reference my problem couldn't be solved but then I tried to use setAdapter() method after fetching data and now my problem is solved . But what I'm asking is Is it unusual to use setAdapter more than once? . In my first attempt I was setting adapter first then trying to use adp.notifyDataSetChanged() after fetching data from server. but now I'm setting adapter again after getting data.
Code:
private List<TImelineDataList> timelineDatalist;
#Override
public void onViewCreated(#NonNull View v, #Nullable Bundle savedInstanceState) {
timelineDataList= new ArrayList<>();
adapter=new CustomRecyclerViewAdapter(timelineDataList);
recyclerView.setItemViewCacheSize(30);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
recyclerView.setLayoutManager(new
LinearLayoutManager(ctx,LinearLayoutManager.HORIZONTAL,false));
recyclerView.setAdapter(adapter);
}
void addTimelineData(String email,String time,String img_link,String caption){
timelineDataList.add(new TimelineData(email,time,img_link,caption));
adapter=new CustomRecyclerViewAdapter(timelineDataList);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
private Emitter.Listener handlePosts = new Emitter.Listener(){
#Override
public void call(final Object... args){
try {
JSONArray jsonArray=(JSONArray)args[0];
for(int i=0;i<jsonArray.length();i++){
try {
JSONObject ob=jsonArray.getJSONObject(i);
demo_email=ob.getString("_pid");
demo_time=ob.getString("time");
demo_link=ob.getString("img_link");
demo_caption=ob.getString("caption");
addTimelineData(demo_email,demo_time,demo_link,demo_caption);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("error",e.toString());
}
}
};
Finally I figured out the problem . The problem was there in constructing adapter twice . Now I've removed the next adapter construction and the setAdapter() as well and it's working without any errors.
Previous Code:
private List<TImelineDataList> timelineDatalist;
#Override
public void onViewCreated(#NonNull View v, #Nullable Bundle savedInstanceState) {
timelineDataList= new ArrayList<>();
**adapter=new CustomRecyclerViewAdapter(timelineDataList);**//Here
recyclerView.setItemViewCacheSize(30);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
recyclerView.setLayoutManager(new
LinearLayoutManager(ctx,LinearLayoutManager.HORIZONTAL,false));
recyclerView.setAdapter(adapter);
}
void addTimelineData(String email,String time,String img_link,String caption){
timelineDataList.add(new TimelineData(email,time,img_link,caption));
**adapter=new CustomRecyclerViewAdapter(timelineDataList);**//Here
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
private Emitter.Listener handlePosts = new Emitter.Listener(){
#Override
public void call(final Object... args){
try {
JSONArray jsonArray=(JSONArray)args[0];
for(int i=0;i<jsonArray.length();i++){
try {
JSONObject ob=jsonArray.getJSONObject(i);
demo_email=ob.getString("_pid");
demo_time=ob.getString("time");
demo_link=ob.getString("img_link");
demo_caption=ob.getString("caption");
addTimelineData(demo_email,demo_time,demo_link,demo_caption);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("error",e.toString());
}
}
};
New Code:
private List<TImelineDataList> timelineDatalist= new ArrayList<>();;
#Override
public void onViewCreated(#NonNull View v, #Nullable Bundle savedInstanceState) {
adapter=new CustomRecyclerViewAdapter(timelineDataList);
recyclerView.setItemViewCacheSize(30);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
recyclerView.setLayoutManager(new
LinearLayoutManager(ctx,LinearLayoutManager.HORIZONTAL,false));
recyclerView.setAdapter(adapter);
}
void addTimelineData(String email,String time,String img_link,String caption){
timelineDataList.add(new TimelineData(email,time,img_link,caption));
adapter.notifyDataSetChanged():
}
private Emitter.Listener handlePosts = new Emitter.Listener(){
#Override
public void call(final Object... args){
try {
JSONArray jsonArray=(JSONArray)args[0];
for(int i=0;i<jsonArray.length();i++){
try {
JSONObject ob=jsonArray.getJSONObject(i);
demo_email=ob.getString("_pid");
demo_time=ob.getString("time");
demo_link=ob.getString("img_link");
demo_caption=ob.getString("caption");
addTimelineData(demo_email,demo_time,demo_link,demo_caption);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("error",e.toString());
}
}
};
Call adapter.notifyDataSetChanged() method to update RecyclerView adapter after adding data into arraylist which is attached to adapter.
You can also call method notifyItemInserted(index) which can show item added with animation effect.
The proper way is to call notifyDataSetChanged on the adapter or other methods from that family.
The problem with setting adapter will be that your scroll position will be lost.
It looks like the problem is in your CustomRecyclerViewAdapter. Good practice is to move timelineDatalist into the CustomRecyclerViewAdapter and have something like:
void addTimelineData(String email,String time,String img_link,String caption){
adapter.addToTimelineDataList(new TimelineData(email,time,img_link,caption));
adapter.notifyDataSetChanged();
}
Please post your CustomRecyclerViewAdapter for more details.
I think its usual to use setAdapter multiple times as it won't create any issues in functionality. But if you want to use
notifyDataSetChanged()
then try not to reinitialize your data while receiving the data if you perform
yourData = newData
then this will reinitialize your old data and notifyDataSetChanged() will not work on that
if its string then try concatenating in the current instance.
make some change in method like below code ..
void addTimelineData (String email, String time, String img_link, String caption){
timelineDataList.clear()
timelineDataList.add(new TimelineData(email, time, img_link, caption));
setAdapter();
}
and make one setAdapter method like..
public void setAdapter(){
if (adpter==null){
if(!timelineDataList.isEmpty()){
adapter = new CustomRecyclerViewAdapter(timelineDataList);
}
}
else{
adapter.notifyDataSetChanged();
}
}
and remove the code onCreate() define recyclerView.setAdapter(adapter);

android firebase reads all the database

i am trying to read a specific child in Firebase which i named Tags. the problem is, i just can't put the object from tags (dados.getValue) into a ArrayList to later populate in my ListView.
I know is simple, sorry about that, ut i am new here in android
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_taglist);
tags = new ArrayList<>();
tagList = (ListView) findViewById(R.id.tagsList);
tagsRefs = FirebaseConfig.getFireBase();
tagsRefs.child("tags").child("categorias");
tagsRefs.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dados : dataSnapshot.child("tags").getChildren()) {
System.out.println("tag EXTRAIDA NO taglist " + dados.getValue());
dados.getValue(); //HOW CAN I PUT THIS INTO AN ARRAY TO LATER ADD IN MY ArrayList tags??
String tagS = dados.getValue(String.class);
tags.addAll(tagS);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
tagAdapter = new ArrayAdapter(getBaseContext(), android.R.layout.simple_list_item_2,
android.R.id.text1,
tags);
tagList.setAdapter(tagAdapter);
tagList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedTag = (String) tagList.getItemAtPosition(position);
setSelectedTag(selectedTag);
}
});
}
here is my database:
h
This is happening because onDataChange() method is called asynchronously. This means that the statement that adds tags to your list is executed before onDataChange() method has been called. That's why your list is empty outside that method. So in order to use that lists, you need to use it inside the onDataChange().
For other approach, please visit this post and this post.
Hope it helps.

Android ListView does not show list items

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

Categories

Resources