Populate spinner upon clicking it - java

I am trying out this simple program where I try to send a POST request to the server and fetch the response and store them into the spinner. This is my code;
fetchcolonynames("code"); //sending POST request
if (spin1 != null) {
//spin.setAdapter(adapter) doesn't work here
spin1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
spin1.setAdapter(adapter); //doesn't work spinner shows nothing on clicked
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
This is my fetchcolonynames() method:
private void fetchcolonynames(String input){
call=api.fetchcolonynames(input);
if(call!=null){
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.body() != null) {
JSONArray array = null;
try {
array = new JSONArray(response.body());
for(int i=0;i<array.length();i++){
arr.add(array.getString(i));
}
} catch (JSONException e) {
e.printStackTrace();
}
Collections.sort(arr); //data is correct here
adapter = new ArrayAdapter<String>(view.getContext(), android.R.layout.simple_spinner_item,arr);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
}
}
All my variables are globally declared. I want to populate the spinner, when the user clicks it. How do I accomplish this?

Related

How can I refresh the listview after I delete my draft when it automatically re-presses?

How can i refresh listview after I delete my draft when it automatically back pressed?
public void deleteDraft() {
((LoaderActivity) getActivity()).getLoader().show();
ApiHelper.get().itrDeleteDraft(new ItrDeleteDraftApi.Request(userID, projectID, itrRaisedID)).enqueue(new ApiRequest.Callback<ItrDeleteDraftApi.Response>() {
#Override
public void onSuccess(ItrDeleteDraftApi.Response response) {
((LoaderActivity) requireActivity()).getLoader().hide();
requireActivity().onBackPressed();
}
#Override
public void onFailure(String e) {
((LoaderActivity) getActivity()).getLoader().hide();
ErrorManager.promptError(getActivity(), e);
}
});
}
#OnClick(R.id.buttons_itr_delete) public void onDeleteButtonClick(){
new AlertDialog.Builder(getContext()).setCancelable(false).setTitle("").setMessage(R.string.confirm_delete_itr).setNegativeButton(R.string.cancel, (d,e)->d.dismiss()).setPositiveButton(R.string.ok, (d,e)-> {
itrDetailFragment.deleteDraft();
}).create().show();
}
It will refresh or else it will disappear in the list

How to Pass Original Value of Array Item after using Matcher and regex

So In my app I have a few spinners the one spinner gives a Hourly Rate,
the data in the spinner I have edited using Matcher,regex etc. so that they display correctly in the spinner
but what I can't figure out is I have to pass the original string of the Array Item on item select to a URL builder And I have No Idea how to do this at all and have googled for hours now
so the original
object looks like this
7 - 1 - R100
so I used Matcher and Pattern to trim that value in the spinner to display just
R100
But now I have to pass the original value of
7 - 1 - R100
To a URI Builder
Here is the code for populating the spinner
private void LoadUserRatesSpinnerData(String url) {
RequestQueue requestQueue=Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject=new JSONObject(response);
if (jsonObject.getInt("success") == 1) {
JSONArray jsonArray=jsonObject.getJSONArray("Name");
for (int i=0; i < jsonArray.length(); i++) {
JSONObject jsonObject1=jsonArray.getJSONObject(i);
String rates=jsonObject1.getString("UserRate");
for(int p=0; p < 100; p++){
final Matcher matcher=Pattern.compile(" - ").matcher(rates);
if (matcher.find()) {
rates=rates.substring(matcher.end()).trim();
}
}
UserRate.add(rates);
}
}
UserRatesSpinner.setAdapter(new ArrayAdapter<>(IntTimeLog.this, android.R.layout.simple_spinner_dropdown_item, UserRate));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
int socketTimeout=30000;
RetryPolicy policy=new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy);
requestQueue.add(stringRequest);
}
The onItemSelected code for the spinner
UserRatesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#SuppressLint("SetTextI18n")
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
if (position == 0) {
UserRatesSpinner.setClickable(true);
} else {
UserRatesSpinner.setClickable(true);
UserRates=UserRatesSpinner.getSelectedItem().toString();
}
if (LogHour.getText().toString().contains("Hours Logged")) {
LogHour.setText("Log Hours");
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
At the Moment only the R100 gets passed to the URI builder
You should declare a new variable, I called it trimmedRates. As it stands your code is overwriting the variable rates.
String trimmedRates;
if (matcher.find()) {
trimmedRates=rates.substring(matcher.end()).trim();
}
So I solved this Issue by making another ArrayList and adding the original Json data before I adding the data from the matcher to a seprate arraylist,
Here is the code
private void LoadTaskSpinner(String url) {
final ProgressDialog pd=new ProgressDialog(IntTimeLog.this);
pd.setMessage("Please Wait..Loading Time Log Data");
pd.setCanceledOnTouchOutside(false);
pd.show();
RequestQueue requestQueue=Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.cancel();
try {
JSONObject jsonObject=new JSONObject(response);
if (jsonObject.getInt("success") == 1) {
JSONArray jsonArray=jsonObject.getJSONArray("Name");
for (int i=0; i < jsonArray.length(); i++) {
JSONObject jsonObject1=jsonArray.getJSONObject(i);
String task=jsonObject1.getString("TaskName");
TaskName.add(task);
}
}
taskSpinner.setAdapter(new ArrayAdapter<>(IntTimeLog.this, android.R.layout.simple_spinner_dropdown_item, TaskName));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
LoadErrorSpinner(ClientsUrl);
error.printStackTrace();
}
});
int socketTimeout=30000;
RetryPolicy policy=new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy);
requestQueue.add(stringRequest);
}
And then in the Item selection I used IF statements to get the correct String to the URL
UserRatesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#SuppressLint("SetTextI18n")
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
if (position == 1) {
SelectedSpin = ItemSelect.get(1);
}
else{
UserRatesSpinner.setClickable(true);
}
if (position == 2) {
SelectedSpin = ItemSelect.get(2);
}
else {
UserRatesSpinner.setClickable(true);
}
if (position == 3) {
SelectedSpin = ItemSelect.get(3);
}
else{
UserRatesSpinner.setClickable(true);
}
if (LogHour.getText().toString().contains("Hours Logged")) {
LogHour.setText("Log Hours");
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});

SwipeRefresh layout progress bar is not hiding even after completion

I am using MVVM pattern in which I am using SwipeRefresh layout to refresh recycler view in my layout.When I am pulling it then it continue to refresh even after method completed successfully.
Below is my code:
MainActivity.java
refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
userRepository.getUserList();
}
});
UserRepository.java
public void getUserList(){
Retrofit retrofit = RetrofitClient.getInstance();
ApiService apiService = retrofit.create(ApiService.class);
Call<List<User>> userList = apiService.getUser();
userList.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(Call<List<User>> call, final Response<List<User>> response) {
Completable.fromAction(new Action() {
#Override
public void run() throws Exception {
if(response.body() != null) {
List<User> list = response.body();
for (int i = 0; i < list.size(); i++) {
String id = list.get(i).get_id();
String names = list.get(i).getName();
String age = list.get(i).getAge();
User user = new User(id,names,age);
userDb.userDao().Insert(user);
}
}
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onComplete() {
Toast.makeText(context,"Data inserted",Toast.LENGTH_SHORT).show();
}
#Override
public void onError(Throwable e) {
Toast.makeText(context,e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onFailure(Call<List<User>> call, Throwable t) {
Toast.makeText(context,t.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
Method fetching list is in another class UserRepository and I am calling method in another activity MainActivity.I am not getting any way how can I stop refreshing process.Someone please let me know a way to stop refreshing process.
Any help would be appreciated.
THANKS
To disable the progress dialog add this,
swipeLayout.setRefreshing(false);

Room LiveData onChange called too fast. Many Activities stacked atop

#Dao
public interface LibraryCoverContentDao {
#Query("SELECT * FROM LibraryCoverContent where rush_id = :rush_id")
LiveData<List<LibraryCoverContent>> getContentsFromRushID(String rush_id);
#Query("DELETE FROM library_cover where rush_id = :rush_id")
void deleteContentsFromRushID(String rush_id);
#Insert(onConflict = REPLACE)
void insertCoverContents(LibraryCoverContent... contents);
}
I want to open another activity once a list LiveData> mLibraryCoverContents is not null.
I am inserting the items downloaded from a retrofit call one by one into the room database, so apparently, my startActivity() call for the next activity happens many a times and multiple-same activities are opened over this activity.
I want only a single activity on top by calling onChanged only after all items of the retrofit call are inserted into db.
Please see the following related code for reference:
public void openReadRushScreen(final int index) {
int count = mCoversList.size();
if(count > index){
mRushIDContent = mLibraryContentRepository.getContentsFromID(mCoversList.get(index).getRush_id());
mRushIDContent.observe(this, new Observer<List<LibraryCoverContent>>() {
#Override
public void onChanged(#Nullable List<LibraryCoverContent> libraryCoverContents) {
Toast.makeText(getActivity(), "ON CHANGED", Toast.LENGTH_SHORT).show();
if(libraryCoverContents!=null && libraryCoverContents.size()>0){
mRushIDContentsList = libraryCoverContents;
if(mRushIDContentsList.size()>0 && mRushIDContentsList.get(0).getRush_id().equals(mCoversList.get(index).getRush_id())){
mRushIDContentsList = new ArrayList<>();
startActivity(ReadRushActivity.getStartIntent(getActivity(), mCoversList.get(index).getRush_id(),
mCoversList.get(index).isRush_audio(),
mCoversList.get(index).getTitle()));
}
}
else {
if(mCoversList!=null && mCoversList.size()>index) getContent(mCoversList.get(index).getRush_id());
}
}
});
}
else Toast.makeText(getActivity(), "Empty Cover", Toast.LENGTH_SHORT).show();
}
public void getContent(String mRushId) {
mApiService = ApiClient.getClient().create(ApiInterface.class);
Call<List<Content>> call = mApiService.getRushContent(mRushId);
if(call!=null){
call.enqueue(new Callback<List<Content>>() {
#Override
public void onResponse(#NonNull Call<List<Content>> call, #NonNull Response<List<Content>> response) {
mContents = response.body();
if(mContents!=null && mContents.size()>0){
//noinspection ConstantConditions
List<LibraryCoverContent> coverContent = new ArrayList<>();
for(int i=0; i<mContents.size(); i++){
coverContent.add(new LibraryCoverContent
(mContents.get(i).getContent_id(), mContents.get(i).getRush_id(),
mContents.get(i).getContent(), mContents.get(i).getAttr(),
mContents.get(i).getDatetime(), mContents.get(i).getPage_no()));
}
mLibraryContentRepository.insertContentItems(coverContent);
}
}
#Override
public void onFailure(#NonNull Call<List<Content>> call, #NonNull Throwable t) {
// if(getActivity()!=null) Toast.makeText(getActivity(), "Network Error while downloading rush content", Toast.LENGTH_LONG).show();
}
});
}
}
#SuppressLint("StaticFieldLeak")
public void insertContentItems(final List<LibraryCoverContent> items) {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
for(int i=0; i<items.size(); i++){
mLibraryCoverContentDao.insertCoverContents(items.get(i));
}
return null;
}
}.execute();
}

Updating listview isn't working

So basically I'm collecting data from a json url in my listview. It's a chatroom type of app and in the lists I want to sync the chatroom contact lists with latest message and timestamps.
When the json gets updated I'm calling the fuction.
public void addGroupAdapter() {
Firebase jsonurl = new Firebase("firebase url");
jsonurl.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ContactListAdapter adapter = new ContactListAdapter(getContext(),dataSnapshot);
try {
Log.i("Response Array fire",new JSONArray(dataSnapshot.getValue(String.class)).toString());
if (!adapted){
chatLists.setAdapter(adapter);
adapted = true;
}else {
Log.i("update",dataSnapshot.getValue(String.class));
adapter.setContactList(dataSnapshot);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
That Json data is stored in the firebase database .
chatLists.setAdapter(adapter) works well.
But when I try to update. notifyDataSetChanged(); doesn't work.
new ContactListAdapter(getContext(),dataSnapshot).notifyDataSetChanged();
I also tried invalidateviews method and same result. So where am I doing wrong?
After reading answers I tried this. SO now this my adapter class,
class ContactListAdapter extends BaseAdapter {
Context c;
List lists;
Type type = new TypeToken<List<ChatroomLists>>(){}.getType();
JsonParser parser = new JsonParser();
ArrayList<ChatroomLists> ob1 = new ArrayList<ChatroomLists>();
public void setContactList(DataSnapshot dataSnapshot) {
Type listType = new TypeToken<ArrayList<ChatroomLists>>() {
}.getType();
ob1 = new Gson().fromJson((JsonArray)parser.parse(dataSnapshot.getValue(String.class)),listType);
Log.i("setContactList",dataSnapshot.getValue(String.class));
notifyDataSetChanged();
}
ContactListAdapter(Context c, DataSnapshot group_name) {
this.c = c;
this.groupids = group_name;
Type listType = new TypeToken<ArrayList<ChatroomLists>>() {
}.getType();
ob1 = new Gson().fromJson((JsonArray)parser.parse(group_name.getValue(String.class)),listType);
}
#Override
public int getCount() {
return ob1.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
GroupChat.viewHolder holder = null;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) c.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate (R.layout.chat_list_style, parent, false);
holder = new GroupChat.viewHolder(row);
row.setTag (holder);
} else {
holder = (GroupChat.viewHolder) row.getTag ();
}
ChatroomLists chatroomLists = ob1.get(position);
Iterator<ChatroomLists> iter = ob1.iterator();
String id = chatroomLists.getId();
String time = chatroomLists.getTimestamp();
Log.i("updated data",id + time);
viewHolder finalHolder = holder;
Firebase chatlink = new Firebase ("firebase link");
chatlink.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot d: dataSnapshot.getChildren()){
finalHolder.user_message.setText (dataSnapshot.child(d.getKey()).child("message").getValue(String.class));
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Firebase imageurl = new Firebase("firebase link");
imageurl.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Glide.with (getActivity ())
.load (dataSnapshot.getValue(String.class))
.error (R.drawable.man)
.into (finalHolder.user_img);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
holder.user_name.setText (id);
row.setOnClickListener (new View.OnClickListener () {
#Override
public void onClick(View v) {
Intent intent = new Intent (getActivity (), ChatRoom.class);
intent.putExtra ("group_name", id);
startActivity (intent);
}
});
registerForContextMenu (row);
return row;
}
}
But it's still not updating.. :(
UPDATE: Listview was so buggy in this case. And I changed to Recyclerview. Now everything is working smoothly.
This is because you are creating new adapter instance instead of updating data on existing adapter which is set on list/recyclerview.
private ContactListAdapter mAdatper;
public void addGroupAdapter() {
Firebase jsonurl = new Firebase("firebase url");
jsonurl.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
try {
Log.i("Response Array fire",new JSONArray(dataSnapshot.getValue(String.class)).toString());
if (!adapted){
mAdatper = new ContactListAdapter(getContext(),dataSnapshot);
chatLists.setAdapter(mAdapter);
adapted = true;
}else {
Log.i("update",dataSnapshot.getValue(String.class));
mAdatper.setContactList(dataSnapshot);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
In your adapter, add setter method.
public void setContactList(DataSnapshot dataSnapshot) {
// set contactList here
notifyDataSetChanged();
}
Hope it might be helpful for you.
You are calling notifyDataSetChanged() on a new instance of the adapter everytime. You should call it on the same adapter that you set on the list. And you should update the data in that particular instance of the adapter
In your else case you are creating a new ContactListAdapter but you are not attaching that adapter to your chatLists. Anyway, you do not need to create a new CustomAdapter instance, just create a update method within your CustomAdapter and call it passing new dataSnapshot data.
You can Try something as the following inside your CustomAdapter.java:
public void updateData(Data data) {
this.dataList = data;
notifyDataSetChanged();
}
Then back into your addGroupAdapter method just call that method

Categories