I have to create a RecyclerView which is updated every time a new item is created by my AsyncTask. So the RecyclerView is building itself up gradually.
Every Item is generated and then the Thread sleeps for a time to see the progress slower.
I tried to get the Adapter and update it with notifyDataSetChanged(), but it wont work like this. The Error I get is:
Only the original thread that created a view hierarchy can touch its
views.
Another idea was to update the adapter in my MainActivity with the use of a interface. But I dont exactly know how to do that. First I have to know if its the right way to use an interface or if there is a better way or maybe a really easy solution for my problem.
public class MainActivity extends AppCompatActivity implements ListAdapter.Listener{
static RecyclerView recyclerView;
static ListAdapter adapter;
#Override
public void click(String name) {
if(getResources().getConfiguration().orientation== Configuration.ORIENTATION_LANDSCAPE){
DetailsFragment detailsFragment = (DetailsFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_details);
detailsFragment.setData(name);
}
else{
Toast.makeText(this, "clicked", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, DetailsActivity.class);
intent.putExtra("sorte_name", name);
startActivity(intent);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerView();
new DataContainer().execute();
}
private void initRecyclerView(){
recyclerView = findViewById(R.id.meinRecyclerView);
adapter = new ListAdapter(this, DataContainer.meineSortenListe, this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
public class DataContainer extends AsyncTask<Void, Void, Void> {
public static ArrayList<String> meineSortenListe = new ArrayList<String>();
ListAdapter myAdapter;
#Override
protected void onPreExecute() {
myAdapter =(ListAdapter)MainActivity.recyclerView.getAdapter();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
for(int i= 0; i<50; i++){
meineSortenListe.add("Sorte "+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
onProgressUpdate();
}
Log.i("info", "array befüllt");
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
myAdapter.notifyDataSetChanged();
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder>{
private ArrayList<String> mSorten;
private Context mContext;
private Listener listener;
public interface Listener{
void click(String name);
}
//Constructor
public ListAdapter(Context mContext, ArrayList<String> sortenListe, Listener listener) {
this.mContext = mContext;
this.mSorten = sortenListe;
this.listener=listener;
}
///////////////////////
public class ViewHolder extends RecyclerView.ViewHolder {
TextView sortenName;
LinearLayout sorteLayout;
public ViewHolder(View itemView) {
super(itemView);
sortenName = itemView.findViewById(R.id.nameSorte);
sorteLayout = itemView.findViewById(R.id.sorteLayout);
}
}
////////////////////////////////
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
holder.sortenName.setText(mSorten.get(position));
holder.sorteLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.click(mSorten.get(position));
}
});
}
#Override
public int getItemCount() {
return mSorten.size();
}
}
In Android, only the UI thread can update views. (It is possible to trigger UI updates in onPostExecute, since onPostExecute is switching to the UI thread.)
Since you are still in the doInBackground() function, you need a Handler to send a Runnable with your code to the UI thread's MessageQueue.
So in your DataContainer, change onProgressUpdate to
protected void onProgressUpdate(Void... values) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable(){
public void run() {
myAdapter.notifyDataSetChanged();
}
});
super.onProgressUpdate(values);
}
Related
I would like to get data from the box which click on on the recycler view to go into a another activity to display.
I have tried to flow this video https://www.youtube.com/watch?v=7GPUpvcU1FE&t=399s&ab_channel=PracticalCoding i dont understand at 6:16.
Also https://www.youtube.com/watch?v=VQKq9RHMS_0&ab_channel=Stevdza-San i cannot get the data to pass to the new activity.
Main code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_staff_home);
DB=new mainTextDBHelper(this);
recyclerView=findViewById(R.id.recyclerview);
Title=new ArrayList<>();
description=new ArrayList<>();
radiogroup=new ArrayList<>();
adapter=new recyclerviewAdapter(this,Title,description,radiogroup,listener);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
displaydata();
setOnClickListner();
private void setOnClickListner() {
listener=new recyclerviewAdapter.RecyclerViewClickListener() {
#Override
public void onClick(View v, int position) {
Intent intent=new Intent(getApplicationContext(),cardviewclickon.class);
intent.putExtra("Title",Title.get(position));
startActivity(intent);
}
};
}
private void displaydata() {
Cursor cursor=DB.getdata();
if(cursor.getCount()==0){
Toast.makeText(staff_home.this,"No Entry Exists", Toast.LENGTH_SHORT).show();
return;
}else{
while(cursor.moveToNext())
{
Title.add(cursor.getString(1));
description.add(cursor.getString(2));
radiogroup.add(cursor.getString(3));
}
}
}
recyclerview Adapter code
public class recyclerviewAdapter extends RecyclerView.Adapter<recyclerviewAdapter.MyViewHolder>{
private Context context;
private ArrayList Title_id,description_id,radiogroup_id;
private RecyclerViewClickListener listener;
public recyclerviewAdapter(Context context, ArrayList title_id, ArrayList description_id, ArrayList radiogroup_id,RecyclerViewClickListener listener) {
this.context = context;
Title_id = title_id;
this.description_id = description_id;
this.radiogroup_id = radiogroup_id;
this.listener=listener;
}
#NonNull
#Override
public recyclerviewAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.userentry,parent,false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull recyclerviewAdapter.MyViewHolder holder, int position) {
holder.Title_id.setText(String.valueOf(Title_id.get(position)));
holder.description_id.setText(String.valueOf(description_id.get(position)));
holder.radiogroup_id.setText(String.valueOf(radiogroup_id.get(position)));
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(context,cardviewclickon.class);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return Title_id.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView Title_id,description_id,radiogroup_id;
CardView cardView;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
Title_id=itemView.findViewById(R.id.textTitle);
description_id=itemView.findViewById(R.id.textdescription);
radiogroup_id=itemView.findViewById(R.id.textsrverity);
cardView=itemView.findViewById(R.id.card);
new View.OnClickListener() {
#Override
public void onClick(View view) {
listener.onClick(view,getAdapterPosition());
}
};
}
#Override
public void onClick(View view) {
listener.onClick(view,getAdapterPosition());
}
}
public interface RecyclerViewClickListener{
void onClick(View v,int position);
}
}
If you want to pass data from one activity to other you can use PutExtra() method of the Intent class As I can see you are doing everything pretty much well but you have to catch these extra from the class you are passing like:- I want to pass data from recyclerView to CardViewClass I can do it like:-
In RecyclerView.java file:-
public void sendDataAndOpen(String title) {
Intent intent = new Intent(getApplicationContext(), CardViewClass.class);
intent.putExtraString("Title",Title); // You can use putExtra to put any datatype
startActivity(intent);
}
In CardViewClass.java file (Lets catch our passing data):-
public void onCreate(...) {
....
String title = getIntent().getExtraString("Title") // You can also use ExtraPut and // Must use Same Id
// Use data as you want
.....
}
I'm pulling the weekly data of students from firebase and adding an arraylist inside a class and I return this arraylist to Teacheractivity and I send this arraylist to spinner inside spinner class when i run emulator i can see data in spinner but when i click nothing happens. It doesn't give any error. I wrote it in separate classes to write clean code. Could this be a problem? I don't understand why this happened.
My TeacherActivity
public class TeacherDersActivity extends AppCompatActivity {
ActivityTeacherDersBinding binding;
String lesson_name;
ArrayList<String> WeekContentArraylist;
_Spinner spinner;
GetWeeks getWeeks;
static void SpinnerList(_Spinner spinner)
{
spinner.init();
}
public void init() {
Intent intent = getIntent();
lesson_name= intent.getStringExtra("teacher_lesson");
getWeeks = new GetWeeks(this);
WeekContentArraylist = getWeeks.GetWeekContent(lesson_name);
spinner = new _Spinner(TeacherDersActivity.this, WeekContentArraylist);
SpinnerList(spinner);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityTeacherDersBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
init();
}
}
GetWeeks class from which I pull data from Firebase
My GetWeeks class
public class GetWeeks {
FirebaseFirestore mFirestore;
ArrayList<String> arrayListWeekContent;
Activity _activity;
public GetWeeks(Activity activity)
{
_activity = activity;
mFirestore = FirebaseFirestore.getInstance();
arrayListWeekContent = new ArrayList<>();
}
public void init()
{
}
protected ArrayList<String> GetWeekContent(String lesson_name)
{
mFirestore.collection("Lessons")
.document(lesson_name)
.collection("Documents")
.document("Docs1")
.get()
.addOnSuccessListener(_activity, new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(#NonNull DocumentSnapshot documentsnapshots) {
arrayListWeekContent.add(documentsnapshots.getString("Week1"));
arrayListWeekContent.add(documentsnapshots.getString("Week2"));
arrayListWeekContent.add(documentsnapshots.getString("Week3"));
arrayListWeekContent.add(documentsnapshots.getString("Week4"));
arrayListWeekContent.add(documentsnapshots.getString("Week5"));
arrayListWeekContent.add(documentsnapshots.getString("meetLink"));
}
}).addOnFailureListener(_activity, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
System.out.println("GetWeeks FAIL");
}
});
return arrayListWeekContent;
}
}
My Spinner class
public class _Spinner extends Activity {
Activity activityTeacherDers;
ArrayList<String> WeekContentArraylist;
public _Spinner(Activity activityTeacherDers, ArrayList<String> WeekContentArraylist)
{
this.activityTeacherDers = activityTeacherDers;
this.WeekContentArraylist= WeekContentArraylist;
}
public void init()
{
Spinner spinner = activityTeacherDers.findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(activityTeacherDers,
android.R.layout.simple_spinner_item,WeekContentArraylist);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
adapter.notifyDataSetChanged();
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
System.out.println("Heloooasdasdsa dataa "); //<---- nothing happen hear
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
}
I have Recycler ListView which I show in MainActivity and the first item it is as selected, I have done to click for another items but the last stays clicked and when I try to take this recycler view to show me in next Activity it doesn't work.
The first item it is selected but I have a click method which when click an image makes as selected but when I click a new image this works but the first item stays as selected so continues for others images. I want only a image to be selected.
I don't want to write twice the same code.
Is it good if I have a class only for this method which I can use everytime I want.
The id of recycler view list it is the same on both xml's.
If you have any suggestion for my question please let me know.
This is the adapter for the RecyclerView.
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder>{
private int selectedItem;
private ArrayList<Integer> mImages = new ArrayList<>();
private ArrayList<String> mSearchUrl = new ArrayList<>();
private Context mContext;
public ListViewAdapter(ArrayList<Integer> images, ArrayList<String> SearchUrl, Context context) {
mImages = images;
mContext = context;
mSearchUrl = SearchUrl;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.s_engine_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int i) {
selectedItem = 0;
if (selectedItem == i) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}
Glide.with(mContext).load(mImages.get(i))
.into(viewHolder.image);
viewHolder.searchUrl.setText(mSearchUrl.get(i));
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
selectedItem = i;
}
});
}
#Override
public int getItemCount() {
return mImages.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView searchUrl;
public ViewHolder(#NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.ivEngine);
searchUrl = itemView.findViewById(R.id.ivEngineText);
}
}
}
This is the method in MainActivity.class
public void intSearch() {
mImages.add(R.drawable.s_bing);
mSearchUrl.add("https://www.bing.com/search?q=");
mImages.add(R.drawable.s_google);
mSearchUrl.add("https://www.google.com/search?q=");
mImages.add(R.drawable.s_yahoo);
mSearchUrl.add("www.yahoo.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
initRecyclerView();
}
private void initRecyclerView() {
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = findViewById(R.id.lvEngines);
recyclerView.setLayoutManager(layoutManager);
ListViewAdapter adapter = new ListViewAdapter(mImages, mSearchUrl, this);
recyclerView.setAdapter(adapter);
}
This is the button which takes to another activity.
btnSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newEntry = searchPlugin.getText().toString();
Cursor data = mDatabaseHelper.getData();
AddHistory(newEntry);
getFragmentRefreshListener().onRefresh();
Intent intent = new Intent(MainActivity.this, ActivitySearchEngine.class);
intent.putExtra("name", newEntry);
intent.putExtra("test", mSearchUrl.get(0));
startActivityForResult(intent, 2);
}
});
This is the another activity
public class ActivitySearchEngine extends Activity implements
SwipeRefreshLayout.OnRefreshListener {
public ImageView mHome;
public EditText searchPlugin;
public WebView webView;
Button btnSearch;
public ImageButton clearSearch, exitButton;
public ImageView favIcon;
public ProgressBar loadIcon;
String text;
SwipeRefreshLayout refreshLayout;
DatabaseHelper mDatabaseHelper;
private String selectedName;
private int selectedID;
private String selectedSearchUrl;
RecyclerView mListView;
MainActivity mainActivity = new MainActivity();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result);
mHome = findViewById(R.id.imgBtnHome);
searchPlugin = findViewById(R.id.etSearch);
webView = findViewById(R.id.webView);
clearSearch = findViewById(R.id.btnClearSearch);
btnSearch = findViewById(R.id.btnSearch);
favIcon = findViewById(R.id.imgViewFavIcon);
loadIcon = findViewById(R.id.progressBarIcon);
exitButton = findViewById(R.id.imgBtnStopLoad);
refreshLayout = findViewById(R.id.refreshLayout);
mListView = findViewById(R.id.lvEngines);
refreshLayout.setOnRefreshListener(this);
mDatabaseHelper = new DatabaseHelper(this);
mainActivity.intSearch(); // Here it is the error
Activity.ActivitySearchEngine}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
Intent receivedIntent = getIntent();
selectedName = receivedIntent.getStringExtra("name");
selectedID = receivedIntent.getIntExtra("id",-1); //NOTE: -1 is just the default value
selectedSearchUrl = receivedIntent.getStringExtra("test");
searchPlugin.setText(selectedName);
loadIcon.setVisibility(View.VISIBLE);
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("www.bing.com/search?=" + selectedName);
webView.setWebChromeClient(new WebChromeClient() {
#Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
#Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
favIcon.setImageBitmap(icon);
}
});
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
loadIcon.setVisibility(View.VISIBLE);
favIcon.setVisibility(View.GONE);
}
public void onPageFinished(WebView view, String url) {
try {
if (loadIcon.getVisibility() == View.VISIBLE) {
loadIcon.setVisibility(View.GONE);
favIcon.setVisibility(View.VISIBLE);
btnSearch.setVisibility(View.GONE);
mHome.setVisibility(View.VISIBLE);
exitButton.setVisibility(View.GONE);
clearSearch.setVisibility(View.VISIBLE);
favIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onRefresh();
}
});
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
});
searchPlugin.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
processButtonByTextLength();
}
});
mHome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
searchPlugin.setText(null);
finish();
}
});
clearSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
searchPlugin.setText("");
}
});
public void processButtonByTextLength() {
String inputText = searchPlugin.getText().toString();
if(inputText.length() > 0) {
btnSearch.setVisibility(View.VISIBLE);
mHome.setVisibility(View.GONE);
clearSearch.setVisibility(View.VISIBLE);
favIcon.setVisibility(View.VISIBLE);
loadIcon.setVisibility(View.GONE);
exitButton.setVisibility(View.GONE);
} else if(inputText.length() == 0) {
btnSearch.setVisibility(View.GONE);
mHome.setVisibility(View.VISIBLE);
clearSearch.setVisibility(View.GONE);
}
}
#Override
public void onRefresh() {
webView.reload();
refreshLayout.setRefreshing(false);
}
}
This is the photo with RecyclerView at MainActivity.class
Photo of another Activity
I have kind of to-do app. In profile activity, there are 2 tabs.
To-do and Done. In Tab 1, user can check as "done" of their "to-do". In this case, I want to update TAB 2's recyclerview.
I tried several things, but didn't work. Here is TAB 1 codes, it's almost same as TAB 2.
TAB 1 Class
public class Tab_Profile_1 extends Fragment {
private RecyclerView recyclerView_tab_todo;
private List<Model_ListItem> itemList;
private Adapter_Profile_ToDo adapter_profile_toDo;
SharedPreferences mSharedPref;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile_tab_1, container, false);
//TO-DO
//
recyclerView_tab_todo = view.findViewById(R.id.recyclerView_tab_todo);
//
fetchUserToDo();
return view;
}
public void fetchUserToDo() {
itemList = new ArrayList<>();
//First Settings
mSharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
String session_user_id = mSharedPref.getString("session_user_id", "");
API_Service api_service = Client.getRetrofitInstance().create(API_Service.class);
Call<List<Model_ListItem>> call = api_service.fetchUserToDo(session_user_id);
call.enqueue(new Callback<List<Model_ListItem>>() {
#Override
public void onResponse(Call<List<Model_ListItem>> call, Response<List<Model_ListItem>> response) {
itemList = response.body();
adapter_profile_toDo = new Adapter_Profile_ToDo(getContext(), itemList);
recyclerView_tab_todo.setHasFixedSize(true);
LinearLayoutManager layoutManager
= new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerView_tab_todo.setLayoutManager(layoutManager);
recyclerView_tab_todo.setAdapter(adapter_profile_toDo);
}
#Override
public void onFailure(Call<List<Model_ListItem>> call, Throwable t) {
}
});
}}
TAB 1 RecyclerView Adapter
public class Adapter_Profile_ToDo extends RecyclerView.Adapter {
private Context context;
private List<Model_ListItem> itemList;
private String url_extension_images = URL_Extension.url_extension_images;
SharedPreferences mSharedPref;
ProgressDialog progressDialog;
View view;
public Adapter_Profile_ToDo(Context context, List<Model_ListItem> itemList) {
this.context = context;
this.itemList = itemList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_profile_todo, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
Glide.with(context).load(url_extension_images + itemList.get(position).getItem_image()).into(holder.imageView_profile_todo);
holder.textView_profile_todo_name.setText(itemList.get(position).getItem_name());
holder.textView_profile_todo_desc.setText(itemList.get(position).getItem_description());
holder.layout_profile_todo_detail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//detail
}
});
holder.layout_profile_todo_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getRootView().getContext(), R.style.AlertStyle);
builder.setTitle("\"" + itemList.get(position).getItem_name() + "\"" + "\n");
builder.setIcon(R.drawable.ic_bookmark);
builder.setPositiveButton("YAPTIM", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
showProgressDialog();
addDone("" + itemList.get(position).getItem_id(), position);
}
});
builder.setNegativeButton("SİL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
showProgressDialog();
deleteUserToDo("" + itemList.get(position).getItem_id(), position);
}
});
builder.setNeutralButton("İptal", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
}
});
}
#Override
public int getItemCount() {
return itemList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView_profile_todo;
TextView textView_profile_todo_name, textView_profile_todo_desc;
LinearLayout layout_profile_todo_detail, layout_profile_todo_add;
public ViewHolder(View itemView) {
super(itemView);
imageView_profile_todo = itemView.findViewById(R.id.imageView_profile_todo);
textView_profile_todo_name = itemView.findViewById(R.id.textView_profile_todo_name);
textView_profile_todo_desc = itemView.findViewById(R.id.textView_profile_todo_desc);
layout_profile_todo_detail = itemView.findViewById(R.id.layout_profile_todo_detail);
layout_profile_todo_add = itemView.findViewById(R.id.layout_profile_todo_add);
}
}
public void deleteUserToDo(final String listId, final int clicked) {
mSharedPref = PreferenceManager.getDefaultSharedPreferences(context);
String session_user_id = mSharedPref.getString("session_user_id", "");
API_Service api_service = Client.getRetrofitInstance().create(API_Service.class);
Call<Response_Success> call = api_service.deleteUserToDo(session_user_id, listId);
call.enqueue(new Callback<Response_Success>() {
#Override
public void onResponse(Call<Response_Success> call, Response<Response_Success> response) {
if (response.code() == 200) {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
progressDialog = null;
}
if (response.body().getSuccess().matches("true")) {
Toast.makeText(context, "Silindi!", Toast.LENGTH_SHORT).show();
itemList.remove(itemList.get(clicked));
notifyItemRemoved(clicked);
notifyItemRangeChanged(clicked, itemList.size());
} else {
Toast.makeText(context, "Bilinmeyen bir hata oluştu!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<Response_Success> call, Throwable t) {
Toast.makeText(context, "Bilinmeyen bir hata oluştu!", Toast.LENGTH_SHORT).show();
}
});
}
public void addDone(String listId, final int clicked) {
mSharedPref = PreferenceManager.getDefaultSharedPreferences(context);
String session_user_id = mSharedPref.getString("session_user_id", "");
API_Service apiService = Client.getRetrofitInstance().create(API_Service.class);
Call<Response_Success> call = apiService.addDone(session_user_id, listId);
call.enqueue(new Callback<Response_Success>() {
#Override
public void onResponse(Call<Response_Success> call, Response<Response_Success> response) {
if (response.code() == 200) {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
progressDialog = null;
}
if (response.body().getSuccess().matches("true")) {
Toast.makeText(context, "Eklendi", Toast.LENGTH_SHORT).show();
itemList.remove(itemList.get(clicked));
notifyItemRemoved(clicked);
notifyItemRangeChanged(clicked, itemList.size());
} else {
Toast.makeText(context, "Bilinmeyen bir hata oluştu!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<Response_Success> call, Throwable t) {
}
});
}
public void showProgressDialog() {
progressDialog = new ProgressDialog(view.getRootView().getContext());
progressDialog.setMessage("Yükleniyor");
progressDialog.setCancelable(false);
progressDialog.show();
}
}
If i'm reading this correctly, you have two tabs and a backend database that stores the to do items and their state? To get the second list to update, you just need to do the same thing that you're doing in your first list, and update the adapter's data set and notify that the data set changed. How you trigger this action in your second tab is really the question.
You can either use an interface and have your adapter notify your activity that recycler view 1 had an action on it, and you can then tell adapter 2 to update its data. You can either pass back the data and only notify one row, or you could notify the entire data set. If you're doing this all service based, you could just reload the recycler view from the service and it will have the new data.
I think all you need to figure out is how you want to notify tab 2 that it needs to update its data. My recommendation is:
public interface AdapterInterface
{
void itemCompleted(Item hereIsTheItemThatNeedsToBeAddedTo2);
}
Then inside your adapter have a property with getters/setters such as:
private AdapterInterface adapterInterfaceListener;
Inside your Fragment/Activity implement AdapterInterface and implement the itemCompleted function.
And then set your adapter.setAdapterInterfaceLisetener to that function that you implemented. Then inside your adapter when the user clicks the checkbook to mark it as done, you can call the adapterInterfaceListener.itemCompleted() function, and it will send that information to your Fragment/Activity. From there you can give that new data to adapter2, or recall the API, however you want to get the new data.
Does this help?
I have this method updatePosts() that needs to run inside of a thread. it looks like this
public void updatePosts(){
new Thread(){
public void run(){
posts.addAll(pholder.fetchPosts());
System.out.println("size of posts is " + posts.size());
// UI elements should be accessed only in
// the primary thread, so we must use the
// handler here.
}
}.start();
}
It is literally updating the List called "posts". I have this in my onCreate. The problem is, since it is running in a separate thread, it does not complete before my ImageAdapter needs to use the "posts" List.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
updatePosts();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this, posts));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(MainActivity.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
}
What options do I have to ensure that the updatePosts can finish before the ImageAdapter get created?
You should use an AsyncTask or any other mechanism that lets you offload a task to a background thread with a callback to the UI on completion.
private class BackgroundTask extends AsyncTask<Void, Void, List<Post>> {
#Override
protected List<Post> doInBackground(Void... params) {
// TODO
return posts;
}
#Override
protected void onPostExecute(List<Post> posts) {
// TODO: update UI
}
}
Another option is to use RxJava,
Observable
.fromCallable(new Callable<List<Post>>() {
#Override
public List<Post> call() throws Exception {
// TODO: get posts
return posts;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(posts -> {
// TODO: update UI
}, throwable -> {
// TODO
})
I think you need to use Handler.
private ImageAdapter mAdapter;
private MyHandler mHandler;
private List<YourData> posts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
GridView gridview = (GridView) findViewById(R.id.gridview);
mAdapter = new ImageAdapter(this, posts);
gridview.setAdapter(mAdapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(MainActivity.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
mHandler = new MyHandler(this);
updatePosts();
}
public void updatePosts(){
new Thread(){
public void run(){
posts.addAll(pholder.fetchPosts());
System.out.println("size of posts is " + posts.size());
if (mHandler != null) {
mHandler.sendMessage(mHandler.obtainMessage(1));
}
// UI elements should be accessed only in
// the primary thread, so we must use the
// handler here.
}
}.start();
}
private static class MyHandler extend Handler{
private WeakReference<Your Activity name> outer;
public MyHandler(Your Activity name activity){
outer = new WeakReference<>(activity);
}
#Override
public void handleMessage(Message msg){
switch(msg.what){
case 1:
if(outer.get()!=null){
outer.get().mAdapter.refresh(outer.get().posts);
}
break;
default:break;
}
}
}
And in your ImageAdapter,you need add a method:
public void refresh(List<YourData> dataSet){
this.dataSet = dataSet;
notifyDataSetChanged();
}