i'm tying to load more data each time user reached at the bottom of Recyclerview by get data of next page , using this :
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (!recyclerView.canScrollVertically(1) && isEnd) {
page++;
isEnd = false;
new fetchData().execute(page);
}
}
});
And everything works fine , but i have a problem with animation , each time i load more data Recyclerview disappears and shows.
here's my rest of code :
public class fetchData extends AsyncTask<Integer, List<Wallpaper>, List<Wallpaper>> {
Document doc = null;
ArrayList<Wallpaper> urls = new ArrayList<>();
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected List<Wallpaper> doInBackground(Integer... integers) {
try {
doc = Jsoup.connect(URLSource+"/page/" + integers[0]).get();
} catch (IOException e) {
e.printStackTrace();
}
Elements newsHeadlines = doc.select(".thumbnail");
for (Element headline : newsHeadlines) {
String thumb = headline.select("img").attr("src");
String title = headline.select("img").attr("alt");
Wallpaper wallpaperInfo = new Wallpaper();
URL = URL.replace("/wallpapers/", "/walls/");
wallpaperInfo.setThumbnails(URL);
wallpaperInfo.setTitle(title);
urls.add(wallpaperInfo);
}
return urls;
}
#Override
protected void onPostExecute(List<Wallpaper> wallpapers) {
super.onPostExecute(wallpapers);
setAdapterForRecyclerView(wallpapers);
isEnd = true;
}
}
private void setAdapterForRecyclerView(List<Wallpaper> wallpapers) {
if (myAdapter == null) {
myAdapter = new MyAdapter(wallpapers, getActivity(), new RecyclerViewClickListener() {
#Override
public void onClick(View view, Wallpaper wallpaper) {
Intent intent = new Intent(getActivity(), FullScreen.class);
intent.putExtra("img", wallpaper.getThumbnails());
if (wallpaper.getTitle().isEmpty()) {
intent.putExtra("title", "Unknown");
} else {
intent.putExtra("title", wallpaper.getTitle());
}
startActivity(intent);
/* TODO: FULLSCREEN ACTIVITY HERE*/
}
#Override
public void onClick(View view, Category categories) {
}
});
recyclerView.setAdapter(myAdapter);
} else {
myAdapter.getItems().addAll(wallpapers);
myAdapter.notifyDataSetChanged();
}
progressbar.setVisibility(View.GONE);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (!recyclerView.canScrollVertically(1) && isEnd) {
page++;
isEnd = false;
new fetchData().execute(page);
}
}
});
}
hope you guys help me to stop this animation , i just want to load more data without any animation
i think that your problem is in the calling of setAdapterForRecyclerView as there you may create new adapter instance and set this new adapter to the recyclerview again which lead to this behavior.
i recommend to append the new list of wallpapers objects to the recyclerview list then call notifydatasetchanged
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 months ago.
Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
this code isn't working in real-time.. it works only whenever I restart/refresh the app. I am using Cloud Firestore. plzz change code am noob help me. & sorry For My bad English
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class Category_List_Activity extends BaseActivity {
List<CardModel> list = new ArrayList<>();
RecyclerView recyclerView;
RecyclerAdapter adapter;
android.app.AlertDialog dialog;
private static final String TAG = "CategoryListActivity";
FirebaseFirestore db;
String name, id,node,lastid,time;
boolean islast;
SessionManager sessionManager;
LinearLayout banner;
private InterstitialAd interstitial;
TextView settitel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_list);
FirebaseApp.initializeApp(this);
db = FirebaseFirestore.getInstance();
Bundle bundle = getIntent().getExtras();
banner = findViewById(R.id.banner_bottom_main);
sessionManager=new SessionManager(this);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
StartAppAd.showAd(this);
new AdsHelper().createBanner(this, banner, sessionManager.getBanner());
if (bundle != null) {
name = bundle.getString("name");
id = bundle.getString("id");
lastid = bundle.getString("lastid");
node=bundle.getString("node");
islast=bundle.getBoolean("islast");
}
///////////////////////////Action bar custiom//////////////////////////////////////////
ImageView imgFavorite = (ImageView) findViewById(R.id.previous);
imgFavorite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
ImageView imgFavorsite = (ImageView) findViewById(R.id.refrashing);
imgFavorsite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getData();
}
});
settitel = findViewById(R.id.event_name);
settitel.setText(name);
///////////////////////Action bar custiom end///////////////////////
recyclerView = findViewById(R.id.rec);
adapter = new RecyclerAdapter(list, this);
recyclerView.setHasFixedSize(true);
AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 10000);
recyclerView.setLayoutManager(layoutManager);
// recyclerView.setLayoutManager(new GridLayoutManager(this,1));
recyclerView.setAdapter(adapter);
getData();
if(isCastApiAvailable()) {
castContext = CastContext.getSharedInstance(this);
if (castContext.getCastState() == CastState.CONNECTED) {
findViewById(R.id.castMiniController).setVisibility(View.VISIBLE);
}else{
findViewById(R.id.castMiniController).setVisibility(View.GONE);
}
}else{
findViewById(R.id.castMiniController).setVisibility(View.GONE);
}
}
CastContext castContext;
#Override
protected void onResume() {
super.onResume();
try {
if (HelperClass.vpn(this)) {
finish();
}
}catch (Exception e){
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(#NonNull Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if(item.getItemId() == R.id.refrish){
getData();
return true;
}
else if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
// #Override
// public boolean onOptionsItemSelected(MenuItem item) {
//
// if (item.getItemId() == android.R.id.home) {
// onBackPressed();
// }
//
// return true;
// }
//////////////////sports diglo start///////////////
#Override
public void onDestroy() {
dismissProgressDialog();
super.onDestroy();
}
private void showProgressDialog() {
if (dialog == null) {
dialog = new SpotsDialog.Builder().setContext(this).build();
dialog.setMessage("Please wait...");
dialog.setCancelable(false);
}
dialog.show();
}
private void dismissProgressDialog() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
//////////////////sports diglo end///////////////
private void getData() {
showProgressDialog();
Query query;
if (islast) {
query = db.collection(node)
.document(lastid)
.collection("list")
.document(id)
.collection("list");
} else {
query = db.collection(node)
.document(id)
.collection("list");
}
query.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
dismissProgressDialog();
if (task.isSuccessful()) {
list.clear();
int i = 0;
boolean match = false;
try {
for (DocumentSnapshot snapshot : task.getResult().getDocuments()) {
CardModel mainModel = snapshot.toObject(CardModel.class);
mainModel.setId(snapshot.getId());
if (mainModel.enable) {
boolean onOff=mainModel.cOnOff;
if (mainModel.countries != null
&& mainModel.countries.size() > 0) {
if (!sessionManager.getLocation().isEmpty()) {
if(onOff) {
if (mainModel.countries.contains(sessionManager.getLocation())) {
match = true;
list.add(mainModel);
} else {
list.remove(mainModel);
}
}else{
if (mainModel.countries.contains(sessionManager.getLocation())) {
match = true;
list.remove(mainModel);
} else {
list.add(mainModel);
}
}
} else {
list.add(mainModel);
}
} else {
list.add(mainModel);
}
} else {
list.remove(mainModel);
}
Log.d("view imgs", "data is " + mainModel.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
adapter.notifyDataSetChanged();
dismissProgressDialog();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
dismissProgressDialog();
Toast.makeText(Category_List_Activity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
;
}
}
I am trying to execute the doit() method in OnCreate, waiting for 5 seconds to allow for the method's functionality to fully load and then call the tester() method within the wait function.
The app functions properly without the delay and displays 'TextView' which is the output of the textbox before the function has finished, I would like to wait for 5 seconds until doit() has finished loading and then display the contents of texx from the tester() after the wait. Any help would be appreciated.
Images linked below is a crash output and the app working.
Crash output
App working without delay, but doesn't output textbox content because it hasn't loaded
public class AppHome extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
TextView texx;
private ArrayList<String> al;
private ArrayAdapter<String> arrayAdapter;
private int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_home);
new doit().execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
tester();
}
}, 5000);
}
public void tester() {
texx = findViewById(R.id.text1);
String text = texx.getText().toString();
//String num = text;
String[] str = text.split(",");
final ArrayList al = new ArrayList<String>(Arrays.asList(str));
arrayAdapter = new ArrayAdapter<>(this, R.layout.item, R.id.helloText, al);
SwipeFlingAdapterView flingContainer = findViewById(R.id.frame);
registerForContextMenu(flingContainer);
flingContainer.setAdapter(arrayAdapter);
flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() {
#Override
public void removeFirstObjectInAdapter() {
// this is the simplest way to delete an object from the Adapter (/AdapterView)
Log.d("LIST", "removed object!");
al.remove(0);
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onLeftCardExit(Object dataObject) {
//Do something on the left!
//You also have access to the original object.
//If you want to use it just cast it (String) dataObject
Toast.makeText(AppHome.this, "left", Toast.LENGTH_SHORT).show();
}
#Override
public void onRightCardExit(Object dataObject) {
Toast.makeText(AppHome.this, "right", Toast.LENGTH_SHORT).show();
}
#Override
public void onAdapterAboutToEmpty(int itemsInAdapter) {
// Ask for more data here
al.add("XML ".concat(String.valueOf(i)));
arrayAdapter.notifyDataSetChanged();
Log.d("LIST", "notified");
i++;
}
#Override
public void onScroll(float scrollProgressPercent) {
}
});
// Optionally add an OnItemClickListener
/*
flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener() {
#Override
public void onItemClicked(int itemPosition, Object dataObject) {
}
});
*/
}
public class doit extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... voids) {
String words = "";
try {
Document doc = Jsoup.connect("https://screenscrape4top40.000webhostapp.com/").get();
words = doc.text();
} catch (Exception e) {
e.printStackTrace();
}
return words;
}
#Override
public void onPostExecute(String words) {
super.onPostExecute(words);
texx.setText(words);
}
}
public void showPopup (View v){
PopupMenu popup = new PopupMenu(this, v);
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.dropdown_menu1);
popup.show();
}
#Override
public boolean onMenuItemClick (MenuItem item){
switch (item.getItemId()) {
case R.id.item1:
Toast.makeText(this, "Item 1 clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.item2:
Toast.makeText(this, "Item 2 clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.item3:
Toast.makeText(this, "Item 3 clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.item4:
Toast.makeText(this, "Item 4 clicked", Toast.LENGTH_SHORT).show();
return true;
default:
return false;
}
}
}
move following line in onCreate(), after setContentView() :
texx = findViewById(R.id.text1);
I have a problem with Recyclerview item click. I fetch data to list() method and add via addItem() method in recyclerview custom adapter when scroll down in addOnScrollListener. I get item position with click interface on Fragment. First fetch data work perfectly but when fetch loadmore, can't retrive item positon to new data with onButtonLClick() method.
// in onBindViewHolder;
holder.lnl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
rcylviewItemNotify.onButtonLClick(position);
}catch (Throwable e){
//interface can be null
}
}
});
// addItem() method in adapter;
public void addItem(List<Image> img) {
for (Image im : img) {
arrayList.add(im);
}
notifyDataSetChanged();
}
// interface code;
public interface RcylviewItemNotify {
void onButtonLClick(int position);
}
// in Fragment code;
public void list() {
GetServices service = RetrofitInstance.getRetrofitInstance().create(GetServices.class);
Call<Images> call = service.getImages();
call.enqueue(new Callback<Images>() {
#Override
public void onResponse(Call<Images> call, Response<Images> response) {
Images body = response.body();
records = body.getImages();
adapter.addItem(records);
}
#Override
public void onFailure(Call<Images> call, Throwable t) {
Toast.makeText(getActivity(), "Network hatası onFailure", Toast.LENGTH_SHORT).show();
reflesh.setRefreshing(false);
}
});
}
#Override
public void onButtonLClick(int position) {
final String clickId = String.valueOf(records.get(position).getID());
Toast.makeText(getActivity(), "ID: " + clickId, Toast.LENGTH_SHORT).show();
}
// recycler settings;
public void loadView() {
layoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(layoutManager);
Collections.reverse(records);
adapter = new RecyclerViewAdapter(this,(ArrayList<Image>) records, getActivity());
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
reflesh.setRefreshing(false);
}
I'm not sure if this is your issue but you should be using the ViewHolder to get the position. Inside of your onBindViewHolder:
#Override
public void onClick(View view){
int itemPosition = holder.getAdapterPosition();
// Then do whatever you need to with the position
}
I have a mind-boggling problem I can't seem to solve.
The data in my RecyclerView is not updating, and after an entire day of debugging, I can't find the problematic code. The API returns the correct data, and I parse the correct data in a wallItemList which I pass to the Adapter.
How It Should Behave
After changing the language setting to either one of the 2 (English or Dutch), the items in my Recyclerview should update with it and the title of the element should change to the translated string.
What I Have Tried
Creating a refresh function inside the adapter, and update the wallItemList manually by passing the created wallItemList from the MainActivity and calling notifyDataSetChanged()
Calling notifyDataSetChanged() before, in and after the OnClickListener in the MyRecyclerViewAdapter
Setting the item in onBindViewHolder in the MyRecyclerViewAdapter
Strangely enough, when logging the language of the wallItem just before adapter.setOnItemClickListener in populateRecyclerView(), the language is right. But when I get the string from the object in MyRecyclerViewAdapter's onBindViewHolder, it shows the wrong language.
Here is my MainActivity.java:
public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private List<WallItem> WallItemList;
private RecyclerView mRecyclerView;
private MyRecyclerViewAdapter adapter;
private ProgressBar progressBar;
// LifeCycle variables
private String JSONResults = "";
final static private String JSON_KEY_RESULTS = "";
final static private String WALL_ITEM_LIST_KEY = "";
// SharedPrefences variables
private String APIUrlPreferenceString = "";
private String langPreferenceString = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
// Setup shared preferences
setupSharedPreferences();
// Load the recyclerView
loadRecyclerView(savedInstanceState);
}
private void setLanguageSettings(String lang)
{
//create a string for country
String country = "";
if(lang.equals("en"))
{
country = "EN";
}
else if(lang.equals("nl"))
{
country = "NL";
}
//use constructor with country
Locale locale = new Locale(lang, country);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}
private void setupSharedPreferences()
{
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
APIUrlPreferenceString = sharedPreferences.getString(getString(R.string.pref_api_url_key), getString(R.string.pref_api_url_def_value));
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
// Language settings
if(sharedPreferences.getBoolean(getString(R.string.pref_lang_check_key), true))
{
// Use device settings
setLanguageSettings(Resources.getSystem().getConfiguration().locale.getLanguage());
langPreferenceString = Resources.getSystem().getConfiguration().locale.getLanguage();
}
else
{
// Use preference settings
setLanguageSettings(sharedPreferences.getString(getString(R.string.pref_lang_list_key), getString(R.string.pref_lang_label_en)));
langPreferenceString = sharedPreferences.getString(getString(R.string.pref_lang_list_key), getString(R.string.pref_lang_label_en));
}
}
private void loadRecyclerView(Bundle savedInstanceState)
{
// Lifecycle event to preserve data to prevent repeating API calls
if(savedInstanceState != null && savedInstanceState.containsKey(WALL_ITEM_LIST_KEY) && savedInstanceState.containsKey(JSON_KEY_RESULTS))
{
progressBar.setVisibility(View.GONE);
// Set again in order to preserve state on future rotations
JSONResults = savedInstanceState.getString(JSON_KEY_RESULTS);
// Set wallItemList again in order to preserve state on future rotations
WallItemList = savedInstanceState.getParcelableArrayList(WALL_ITEM_LIST_KEY);
populateRecyclerView();
}
else
{
// First execution
new DownloadTask().execute();
}
}
public class DownloadTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected Boolean doInBackground(Void... params) {
boolean result;
String blindWallResults;
try {
// Error fix, because NetworkUtils.buildUrl returns null when failing
if(null == NetworkUtils.buildUrl(APIUrlPreferenceString))
return false;
// Get response from API
blindWallResults = NetworkUtils.getResponseFromHttpUrl(NetworkUtils.buildUrl(APIUrlPreferenceString));
// Send to parser
JSONResults = blindWallResults;
parseResult(blindWallResults);
result = true;
} catch (IOException e) {
e.printStackTrace();
result = false;
}
// When failed
return result;
}
#Override
protected void onPostExecute(Boolean result) {
progressBar.setVisibility(View.GONE);
// If succeeded
if (result) {
populateRecyclerView();
// Show toast when data has been loaded for the first time
Toast.makeText(MainActivity.this, getString(R.string.json_toast_data_loaded), Toast.LENGTH_SHORT).show();
} else {
// If failed make toast
Toast.makeText(MainActivity.this, getString(R.string.json_toast_data_failed), Toast.LENGTH_SHORT).show();
}
}
}
/**
* Populates recyclerView and adds OnItemClickListener
*/
private void populateRecyclerView()
{
WallItem w = WallItemList.get(0);
adapter = new MyRecyclerViewAdapter(MainActivity.this, WallItemList);
mRecyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(WallItem item) {
// Function to start new activity
Class detailActivity = DetailActivity.class;
// Create intent
Intent startDetailActivityIntent = new Intent(MainActivity.this, detailActivity);
// Add object to intent
startDetailActivityIntent.putExtra("detailWallItem", (Parcelable)item);
// Start activity
startActivity(startDetailActivityIntent);
}
});
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save instances of existing objects
outState.putString(JSON_KEY_RESULTS, JSONResults);
outState.putParcelableArrayList(WALL_ITEM_LIST_KEY, (ArrayList<? extends Parcelable>) this.WallItemList);
}
/**
* Parses JSON result
*
* #param result
*/
private void parseResult(String result) {
WallItemList = new ArrayList<>();
try {
JSONArray mJsonArray = new JSONArray(result);
// Loop through JSON array
for (int i = 0; i < mJsonArray.length(); i++) {
// Get picture URI fragment from JSON
String pictureURIFragment = mJsonArray.getJSONObject(i)
.getJSONArray("images").getJSONObject(0)
.getString("url");
// Load images into String
JSONArray JSONImageArray = mJsonArray.getJSONObject(i)
.getJSONArray("images");
// Create array for wallItem
String[] imageArray = new String[JSONImageArray.length()];
// Loop through JSONArray
for(int x = 0; x < JSONImageArray.length(); x++)
{
String pictureURLFragment = JSONImageArray.getJSONObject(x).getString("url");
// Built picture
URL pictureURL = NetworkUtils.builtPictureUrl(pictureURLFragment.toLowerCase());
imageArray[x] = java.net.URLDecoder.decode(pictureURL.toString());
}
// Built picture
URL pictureURL = NetworkUtils.builtPictureUrl(pictureURIFragment.toLowerCase());
String cleanPictureUrl = java.net.URLDecoder.decode(pictureURL.toString());
// add wall item to the list
WallItem item = new WallItem();
// Set fields of wallItem
item.setThumbnail(cleanPictureUrl);
item.setTitle(mJsonArray.getJSONObject(i).getString("author"));
item.setPhotographer(mJsonArray.getJSONObject(i).getString("photographer"));
item.setAddress(mJsonArray.getJSONObject(i).getString("address"));
item.setMaterial(mJsonArray.getJSONObject(i).getJSONObject("material").getString(langPreferenceString));
item.setDescription(mJsonArray.getJSONObject(i).getJSONObject("description").getString(langPreferenceString));
item.setImgURLArray(imageArray);
// Add wallItem to list
WallItemList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.api_url_settings_item)
{
Intent startSettingsActivity = new Intent(this, SettingsActivity.class);
startActivity(startSettingsActivity);
return true;
}
return super.onOptionsItemSelected(item);
}
private void getDeviceLanguage()
{
Log.d("HERE", Locale.getDefault().getLanguage());
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals(getString(R.string.pref_api_url_key)))
{
// Update String again
APIUrlPreferenceString = sharedPreferences.getString(getString(R.string.pref_api_url_key), getString(R.string.pref_api_url_def_value));
new DownloadTask().execute();
}
if(key.equals(getString(R.string.pref_lang_check_key)))
{
// 1. If true, use system language.
// 2. if System language != en or nl, use default language: en.
// 3. if false, make selectable
}
if(key.equals(getString(R.string.pref_lang_list_key)) || key.equals(getString(R.string.pref_lang_check_key)))
{
// Language settings
if(sharedPreferences.getBoolean(getString(R.string.pref_lang_check_key), true))
{
// Use device settings
setLanguageSettings(Resources.getSystem().getConfiguration().locale.getLanguage());
langPreferenceString = Resources.getSystem().getConfiguration().locale.getLanguage();
}
else
{
// Use preference settings
setLanguageSettings(sharedPreferences.getString(getString(R.string.pref_lang_list_key), getString(R.string.pref_lang_label_en)));
langPreferenceString = sharedPreferences.getString(getString(R.string.pref_lang_list_key), getString(R.string.pref_lang_label_en));
}
// Reload data after executing new Download task
new DownloadTask().execute();
this.recreate();
}
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
#Override
protected void onDestroy() {
super.onDestroy();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
}
}
Here is my MyRecyclerViewAdapter.java
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.CustomViewHolder> {
private List<WallItem> wallItemList;
private Context mContext;
private OnItemClickListener onItemClickListener;
public MyRecyclerViewAdapter(Context context, List<WallItem> wallItemList) {
this.wallItemList = wallItemList;
this.mContext = context;
WallItem w = wallItemList.get(0);
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, null);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
final WallItem wallItem = wallItemList.get(i);
//Download image using picasso library
if (!TextUtils.isEmpty(wallItem.getThumbnail())) {
// Load image into imageView
Picasso.with(mContext).load(wallItem.getThumbnail())
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(customViewHolder.imageView);
}
//Setting text view title
customViewHolder.textView.setText(Html.fromHtml(wallItem.getMaterial()));
// Set OnClickListener to wallItem
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClickListener.onItemClick(wallItem);
}
};
customViewHolder.imageView.setOnClickListener(listener);
customViewHolder.textView.setOnClickListener(listener);
}
// Overwrite to return
#Override
public int getItemCount() {
return (null != wallItemList ? wallItemList.size() : 0);
}
class CustomViewHolder extends RecyclerView.ViewHolder {
protected ImageView imageView;
protected TextView textView;
public CustomViewHolder(View view) {
super(view);
this.imageView = (ImageView) view.findViewById(R.id.thumbnail);
this.textView = (TextView) view.findViewById(R.id.title);
}
}
public OnItemClickListener getOnItemClickListener() {
return onItemClickListener;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
}
My apologies for posting all the code but I can't identify the crucial points and don't have enough experience to pinpoint where it's going wrong. If anyone could help you would it would be greatly appreciated!
I suggest you to initialize and set the adapter in onCreate() method with an empty array of WallItems.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(MainActivity.this, new ArrayList<WallItem>());
mRecyclerView.setAdapter(adapter);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
// Setup shared preferences
setupSharedPreferences();
// Load the recyclerView
loadRecyclerView(savedInstanceState);
}
To update the list of items, I normally have a setItems method inside my adapter that updates the list and calls notifyDataSetChanged()
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.CustomViewHolder> {
...
public void setItems(List<WallItem> items) {
this.wallItemList = wallItemList;
notifyDataSetChanged();
}
}
Your populateRecyclerView method then should call the setItems method to update the new list of items.
private void populateRecyclerView()
{
WallItem w = WallItemList.get(0);
adapter.setItems(WallItemList);
adapter.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(WallItem item) {
// Function to start new activity
Class detailActivity = DetailActivity.class;
// Create intent
Intent startDetailActivityIntent = new Intent(MainActivity.this, detailActivity);
// Add object to intent
startDetailActivityIntent.putExtra("detailWallItem", (Parcelable)item);
// Start activity
startActivity(startDetailActivityIntent);
}
});
}
I didn't test, buy this is how I normally use RecyclerView.
I have a FloatingSearchView in my app to perform some query on my Firestore database. When I check the size of each query, the result is as expected but my view is not updating with the result. I don't understand if this is the queries or if this is how I handle the different adapter.
I have one FirestoreRecyclerAdapter for each query. I don't understand what's wrong. Thank you for your help!
floatingSearchView.setOnSearchListener(new
FloatingSearchView.OnSearchListener() {
#Override
public void onSuggestionClicked(SearchSuggestion
searchSuggestion) {
mLastQuery = searchSuggestion.getBody();
com.google.firebase.firestore.Query qSuggestion =
db
.collection("article")
.whereEqualTo("category", category_key)
.whereEqualTo("type", mLastQuery);
qSuggestion
.get()
.addOnSuccessListener(new
OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot
documentSnapshots) {
int size = documentSnapshots
.getDocuments()
.size();
Toast.makeText(Blog.this, "size " + size,
Toast.LENGTH_LONG).show();
}
});
FirestoreRecyclerOptions<Blog_model> opt = new FirestoreRecyclerOptions.Builder<Blog_model>()
.setQuery(qSuggestion, Blog_model.class)
.build();
Log.d("option", opt.getSnapshots().toString());
suggestionAdapter = new FirestoreRecyclerAdapter<Blog_model, Blog.BlogViewHolder>(opt) {
#Override
public void onBindViewHolder(#NonNull Blog.BlogViewHolder holder, int position, #NonNull final Blog_model model) {
holder.setTitle(model.getTitle());
holder.setDesc(model.getDesc());
holder.setImage(getApplicationContext(), model.getPicture());
final String post_key = getSnapshots().getSnapshot(position).getId();
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Ordinary Intent for launching a new activity
final Intent intent = new Intent(Blog.this, BlogDetails.class);
intent.putExtra("article_id", post_key);
intent.putExtra("category_key", category_key);
intent.putExtra("image", model.getPicture());
intent.putExtra("title", model.getTitle());
startActivity(intent);
}
});
}
#Override
public Blog.BlogViewHolder onCreateViewHolder(ViewGroup group, int i) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.blog_row, group, false);
return new Blog.BlogViewHolder(view);
}
};
floatingSearchView.clearSearchFocus();
mBlogList.setAdapter(suggestionAdapter);
}
#Override
public void onSearchAction(String currentQuery) {
mLastQuery = currentQuery;
// query to firebase
com.google.firebase.firestore.Query qSuggestion =
db
.collection("article")
.whereEqualTo("keyword."+mLastQuery, true);
FirestoreRecyclerOptions<Blog_model> options1 = new FirestoreRecyclerOptions.Builder<Blog_model>()
.setQuery(qSuggestion, Blog_model.class)
.build();
Log.d("option", options1.getSnapshots().toString());
searchAdapter = new FirestoreRecyclerAdapter<Blog_model, Blog.BlogViewHolder>(options1) {
#Override
public void onBindViewHolder(#NonNull Blog.BlogViewHolder holder, int position, #NonNull final Blog_model model) {
holder.setTitle(model.getTitle());
holder.setDesc(model.getDesc());
holder.setImage(getApplicationContext(), model.getPicture());
final String post_key = getSnapshots().getSnapshot(position).getId();
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Toast.makeText(Blog.this, "title", Toast.LENGTH_LONG).show();
// Ordinary Intent for launching a new activity
final Intent intent = new Intent(Blog.this, BlogDetails.class);
intent.putExtra("article_id", post_key);
intent.putExtra("category_key", category_key);
intent.putExtra("image", model.getPicture());
intent.putExtra("title", model.getTitle());
startActivity(intent);
}
});
}
#Override
public Blog.BlogViewHolder onCreateViewHolder(ViewGroup group, int i) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.blog_row, group, false);
return new Blog.BlogViewHolder(view);
}
};
mBlogList.setAdapter(searchAdapter);
}
});
#Override
public void onStart() {
super.onStart();
adapter.startListening();
if(suggestionAdapter != null){
suggestionAdapter.startListening();
}
if(searchAdapter != null){
searchAdapter.startListening();
}
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
if(suggestionAdapter != null){
suggestionAdapter.stopListening();
}
if(searchAdapter != null){
searchAdapter.stopListening();
}
}
You are using two FirestoreRecyclerAdapter objects, which is correct, but the problem in your code is that you are not listening to the second adapter for changes in the right place. To solve this, add inside onSearchAction method:
searchAdapter.startListening();
Right after you create the adapter object. This means that for every character that you type in your FloatingSearchView, you create a new adapter and you populate it with the results that are coming from the database. If you are starting listening in the onStart method, it doesn't help you at all.