RecyclerView items disappear after switching between fragments - android

I have 4 fragments in my app, which managed in NavActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
fab = (FloatingActionButton) findViewById(R.id.fab);
// Fab for fragments
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_DRAGGING:
case ViewPager.SCROLL_STATE_SETTLING:
fab.hide(); // Hide animation
break;
case ViewPager.SCROLL_STATE_IDLE:
switch (viewPager.getCurrentItem()) {
case 0:
fragment1.shareFab(fab);
case 1:
fragment2.shareFab(fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(NavActivity.this, MapsActivity.class));
}
});
break;
default:
fragment1.shareFab(null);
break;
}
if(viewPager.getCurrentItem() == 0 || viewPager.getCurrentItem() == 1)
fab.show(); // Show animation
break;
}
}
});
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new MainFragment(), "Main");
adapter.addFragment(new AboutFragment(), "About");
adapter.addFragment(new CartFragment(), "Cart");
adapter.addFragment(new CatalogFragment(), "Catalog");
viewPager.setAdapter(adapter);
}
///////////new class
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
}
I face one problem, items disappear after switching between fragments i think the implement with RecyclerView And the viewHolder has something to do with it.
Im trying to fetch data with volley from my server, into fragment C (frag num 3), the data streams well everything show correctly.
If i swap to frag B(frag num 2) or D(frag num 4), still everything works.
But if ill swap to frag A(frag num 1) and back to frag 3(where is my list item),
everything goes away, i get blank screen, even if i swap up and down still the items wont download again.
Here is Frag num 3 with my RecyclerView:
private FloatingActionButton mSharedFab;
private List<MyProducts> productsList;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
//Volley Request Queue
private RequestQueue requestQueue;
private int requestCount = 1;
private static final String URL_INDEX = "http://myserverip/android/product.php?page=";
//Tag values to read from json
public static final String TAG_IMAGE_URL = "product_img";
public static final String TAG_PRODUCT_SN = "product_serial_num";
public static final String TAG_PRODUCT_TITLE = "product_title";
public static final String TAG_PRODUCT_PRICE = "product_price";
public static final String TAG_PRODUCT_DESCRIPTION = "product_description";
public CartFragment() {
// Required empty public constructor
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_cart, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(getActivity().getApplicationContext(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setHasFixedSize(true);
//Initializing our superheroes list
productsList = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
//Calling method to get data to fetch data
getData();
//Adding an scroll change listener to recyclerview
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
{
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (isLastItemDisplaying(recyclerView)) {
getData();
}
}
});
}
else
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
recyclerView.setOnScrollChangeListener( new RecyclerView.OnScrollChangeListener()
{
#Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (isLastItemDisplaying(recyclerView)) {
getData();
}
}
});
}
}
//initializing our adapter
adapter = new CustomAdapter(productsList, getActivity());
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
return view ;
}
and the customAdapter class:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
//Imageloader to load image
private ImageLoader imageLoader;
private Context context;
List<MyProducts> myProducts;
public CustomAdapter(List<MyProducts> myProducts, Context context)
{
super();
this.myProducts = myProducts;
this.context = context;
}
#Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.product_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
if( myProducts != null) {
MyProducts myProducts1 = myProducts.get(position);
imageLoader = ImageVolley.getInstance(context).getImageLoader();
imageLoader.get(myProducts1.getProductImage(), ImageLoader.getImageListener(holder.imageView, R.drawable.android_store_log, android.R.drawable.ic_dialog_alert));
//Showing data to the views
holder.imageView.setImageUrl(myProducts1.getProductImage(), imageLoader);
holder.textViewProductTitle.setText(myProducts1.getProductTitle());
holder.textViewProductDescription.setText(myProducts1.getProductDescription());
holder.textViewProductSerialNumber.setText(myProducts1.getProductSn());
holder.textViewProductPrice.setText(myProducts1.getProductPrice());
}
}
#Override
public int getItemCount() {
return myProducts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Views
public NetworkImageView imageView;
public TextView textViewProductTitle;
public TextView textViewProductDescription;
public TextView textViewProductSerialNumber;
public TextView textViewProductPrice;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
textViewProductTitle = (TextView) itemView.findViewById(R.id.textViewProductTitle);
textViewProductDescription = (TextView) itemView.findViewById(R.id.textViewProductDescription);
textViewProductSerialNumber = (TextView) itemView.findViewById(R.id.textViewProductSerialNumber);
textViewProductPrice = (TextView) itemView.findViewById(R.id.textViewProductPrice);
}
}

Try this:
viewPager.setOffscreenPageLimit(3);
Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.
setOffscreenPageLimit

Related

Data is not fetching when swap the tab

I have implemented one app where I have 7 tabs and I used addOnScrollListener to fetch the data when user will scroll the list. My issue is when I move one fragment or tab to another fragment and then come back on the privious tab, the data is not coming on second time on that tab.
Below is my fragment class
public class EI_Pending_Fragment extends Fragment{
SessionManager session;
private List<SuperHero> listSuperHeroes;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
public ProgressBar progressBar;
private RequestQueue requestQueue;
private int requestCount1 = 1;
private Boolean isStarted = false;
private Boolean isVisible = false;
public String email;
public EI_Pending_Fragment() {}
#Override
public void onStart() {
super.onStart();
isStarted = true;
if (isVisible && isStarted){
getData();
}
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isVisible = isVisibleToUser;
if (isStarted && isVisible) {
getData();
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.activity_main_test, container, false);
session = new SessionManager(getActivity());
// get user data from session
HashMap<String, String> user = session.getUserDetails();
email = user.get(SessionManager.KEY_EMAIL);
return view;
}
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
recyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
listSuperHeroes = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getContext());
// getData();
adapter = new CardAdapter(listSuperHeroes, getActivity());
recyclerView.setAdapter(adapter);
progressBar = (ProgressBar) v.findViewById(R.id.progressBar1);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int
newState) {
super.onScrollStateChanged(recyclerView, newState);
if (isLastItemDisplaying(recyclerView)) {
if(requestCount1==1){
exit();
}
else {
getData();
}
}
}
});
}
private JsonArrayRequest getDataFromServer(int requestCount) {
Log.e("email",email);
final String DATA_URL = "http://192.168.2.110/xp/ei_pending_received.php?matri_id="+email+"&page=";
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(DATA_URL + String.valueOf(requestCount),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("response",response.toString());
if(response.length()==0){
requestCount1 = 1;
}
else {
parseData(response);
progressBar.setVisibility(View.GONE);
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
Toast.makeText(getActivity(), "No More Items Available", Toast.LENGTH_SHORT).show();
}
});
return jsonArrayRequest;
}
private void getData() {
requestQueue.add(getDataFromServer(requestCount1));
requestCount1++;
}
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Log.e("array",array.toString().trim());
SuperHero superHero = new SuperHero();
JSONObject json = null;
try {
json = array.getJSONObject(i);
superHero.setImageUrl(json.getString(Config_Test.TAG_IMAGE_URL));
superHero.setMglId(json.getString(Config_Test.TAG_MGLID));
superHero.setAge(json.getString(Config_Test.TAG_AGE));
superHero.setAgeHeight(json.getString(Config_Test.TAG_HEIGHT));
superHero.setCommunity(json.getString(Config_Test.TAG_COMMUNITY));
superHero.setCaste(json.getString(Config_Test.TAG_CASTE));
superHero.setOccupation(json.getString(Config_Test.TAG_OCCUPATION));
superHero.setIncome(json.getString(Config_Test.TAG_INCOME));
superHero.setStatus(json.getString(Config_Test.TAG_STATUS));
superHero.setRequested_On(json.getString(Config_Test.TAG_REQUESTED_ON));
} catch (JSONException e) {
e.printStackTrace();
}
listSuperHeroes.add(superHero);
}
adapter.notifyDataSetChanged();
}
private boolean isLastItemDisplaying(RecyclerView recyclerView) {
if (recyclerView.getAdapter().getItemCount() != 0) {
int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)
return true;
}
return false;
}
void exit(){
Toast.makeText(getContext(),"no more data avilable",Toast.LENGTH_SHORT).show();
}
}
Below is my Activity class where I add all the tab
private void setupViewPager(ViewPager viewPager) {
int numberOfPages=7;
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new NewMatches_Tab(), "New matches");
adapter.addFragment(new Broader_Match_Tab(), "Broader Matches");
adapter.addFragment(new Similar_Matchs_Tab(), "Similar Matches");
adapter.addFragment(new ShortlistTab(), "ShortListed");
adapter.addFragment(new Viewed_My_Profile(), "View My Profile");
adapter.addFragment(new ShortListedMeTab(), "ShortListed Me");
adapter.addFragment(new Photo_Request_Received(), "Photo Request Received");
//viewPager.setOffscreenPageLimit(numberOfPages);
viewPager.setAdapter(adapter);
}
You can add an OnPageChangeListener in the activity and register it to your view pager and do all necessary "setting" within the OnPageChangeListener instance.
ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
//Do your fragment refreshing here
mCurrentPage = position;
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
};
#Override
public void setFragmentsForContents(List<Content> contents) { //bundle data for your different fragments
if(contents!=null){
NUM_PAGES = contents.size();
mContentPager.addOnPageChangeListener(viewPagerPageChangeListener);
mContentPager.setAdapter(mScreenSlidePagerAdapter);
mContentPager.setCurrentItem(mCurrentPage);
}
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return ContentFragment.newInstance(mContents.get(position).getContent());
}
#Override
public int getCount() {
return NUM_PAGES;
}
#NonNull
#Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
#Override
public float getPageWidth(int position) {
return 1.0f;
}
}

SetOnItemClickListener not working inside Fragment

I am using RecycleView to display list of Name and Description. I am using Fragment to view the desired layout. Now, I want to open new Activity onItemClick. I have declared SetOnItemClickListener inside the Fragment, i.e. in "View onCreateView". But it is not working. Here is my code:
This is my java class:
public class TabsHeaderActivity extends AppCompatActivity {
private static final String TAG = TabsHeaderActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs_header);
final Toolbar toolbar = (Toolbar) findViewById(R.id.htab_toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) getSupportActionBar().setTitle("TECHNOLOGY");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final ViewPager viewPager = (ViewPager) findViewById(R.id.htab_viewpager);
setupViewPager(viewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.htab_tabs);
tabLayout.setupWithViewPager(viewPager);
final CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.htab_collapse_toolbar);
try {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.header);
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
#SuppressWarnings("ResourceType")
#Override
public void onGenerated(Palette palette) {
int vibrantColor = palette.getVibrantColor(R.color.primary_500);
int vibrantDarkColor = palette.getDarkVibrantColor(R.color.primary_700);
collapsingToolbarLayout.setContentScrimColor(vibrantColor);
collapsingToolbarLayout.setStatusBarScrimColor(vibrantDarkColor);
}
});
} catch (Exception e) {
// if Bitmap fetch fails, fallback to primary colors
Log.e(TAG, "onCreate: failed to create bitmap from background", e.fillInStackTrace());
collapsingToolbarLayout.setContentScrimColor(
ContextCompat.getColor(this, R.color.primary_500)
);
collapsingToolbarLayout.setStatusBarScrimColor(
ContextCompat.getColor(this, R.color.primary_700)
);
}
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
Log.d(TAG, "onTabSelected: pos: " + tab.getPosition());
switch (tab.getPosition()) {
case 0:
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new DummyFragment(
ContextCompat.getColor(this, R.color.cyan_50)), "Cyan");
adapter.addFrag(new DummyFragment(
ContextCompat.getColor(this, R.color.amber_50)), "Amber");
adapter.addFrag(new DummyFragment(
ContextCompat.getColor(this, R.color.purple_50)), "Purple");
adapter.addFrag(new DummyFragment(
ContextCompat.getColor(this, R.color.grey)), "Grey");
viewPager.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
final MenuItem searchItem = menu.findItem(R.id.menuSearch);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
private static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
public static class DummyFragment extends Fragment {
int color;
Intent intent;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
DessertAdapter adapter = new DessertAdapter(getContext());
recyclerView.setAdapter(adapter);
adapter.SetOnItemClickListener(new DessertAdapter.OnItemClickListener(){
#Override
public void onItemClick(View view, int position) {
switch (position) {
case 3:
intent = new Intent(view.getContext(), LaunchScreenActivity.class);
startActivity(intent);
}
}
});
return view;
}
}
}
This is my Adapter class:
public class DessertAdapter extends RecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts = new ArrayList<>();
OnItemClickListener clickListener;
private Context context;
public DessertAdapter(Context context) {
this.context = context;
desserts = Dessert.prepareDesserts(
context.getResources().getStringArray(R.array.dessert_names),
context.getResources().getStringArray(R.array.dessert_descriptions));
}
#Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_dessert, parent, false);
return new DessertAdapter.DessertVh(view);
}
#Override
public void onBindViewHolder(DessertVh holder, int position) {
Dessert dessert = desserts.get(position);
holder.mName.setText(dessert.getName());
holder.mDescription.setText(dessert.getDescription());
holder.mFirstLetter.setText(String.valueOf(dessert.getFirstLetter()));
}
#Override
public int getItemCount() {
return desserts == null ? 0 : desserts.size();
}
public class DessertVh extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView mName;
private TextView mDescription;
private TextView mFirstLetter;
public DessertVh(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.txt_name);
mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
}
#Override
public void onClick(View v) {
clickListener.onItemClick(v, getPosition());
}
}
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
public void SetOnItemClickListener(final OnItemClickListener itemClickListener) {
this.clickListener = itemClickListener;
}
I am not sure what I am doing wrong. I have checked it in debugger mode. I have put a breakpoint at line:
adapter.SetOnItemClickListener(new DessertAdapter.OnItemClickListener(){
Now, when my Activity is loading debugger comes on this line but, doesn't go inside it. But, when I am clicking something, the debugger doesn't even come on this line, means when I am clicking an item, SetOnItemClickListener doesn't get triggered.
My xml code is:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dummyfrag_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/bg_light">
<android.support.v7.widget.RecyclerView
android:id="#+id/dummyfrag_scrollableview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_horizontal_margin" />
</FrameLayout>
Well, you implemented a normal click listener
DessertVh extends RecyclerView.ViewHolder implements View.OnClickListener
But you never set it.
public DessertVh(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.txt_name);
mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
}
Did you forget about itemView.setOnClickListener(this)?

Android TabLayout with two tabs and a recyclerview in each scrolls to top when switching

I have an Activity with a TabLayout and a Viewpager that contains two tabs. These tabs are one Fragment that is reused which contains a Recyclerview. So each Fragment/Tab contains a recyclerview with a bunch of item.
When switching between these tabs the scroll state isn't retained when I go back to the previous tab.
What am I missing?
Activity:
public class EventsActivity extends AbstractTracActivity implements OnRowClickListener {
#BindView(R.id.toolbar)
Toolbar toolbar;
#BindView(R.id.tabs)
TabLayout tabLayout;
#BindView(R.id.viewpager)
ViewPager viewPager;
private final String TAG = EventsActivity.class.getSimpleName();
private static Context context;
private SearchView searchView;
private static EventListFragment eventsFragment, clubsFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.TracTracAppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.events);
ButterKnife.bind(this);
context = this;
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setLogo(R.drawable.tractrac_logo);
getSupportActionBar().setDisplayShowTitleEnabled(false);
}
eventsFragment = EventListFragment.newInstance(EventListFragment.ListType.EVENTS);
clubsFragment = EventListFragment.newInstance(EventListFragment.ListType.CLUBS);
TabLayout.Tab events = tabLayout.newTab();
TabLayout.Tab clubs = tabLayout.newTab();
tabLayout.addTab(events, 0);
tabLayout.addTab(clubs, 1);
tabLayout.setTabTextColors(ContextCompat.getColorStateList(this, R.color.accent));
tabLayout.setSelectedTabIndicatorColor(ContextCompat.getColor(this, R.color.accent));
ViewPagerAdapter adapter = new ViewPagerAdapter (getSupportFragmentManager());
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
viewPager.setOffscreenPageLimit(2);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
#Override
public void onPageSelected(int position) { }
#Override
public void onPageScrollStateChanged(int state) {
searchView.setQuery("", true);
searchView.clearFocus();
searchView.setIconified(true);
eventsFragment.filterList(null);
clubsFragment.filterList(null);
}
});
}
...
public static class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 1:
return clubsFragment;
default:
return eventsFragment;
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 1:
return context.getResources().getString(R.string.section_clubs);
default:
return context.getResources().getString(R.string.section_events);
}
}
}
}
Fragment:
public class EventListFragment extends Fragment implements EventsFragmentPresenter.ViewInterface {
enum ListType { EVENTS, CLUBS }
private EventsFragmentPresenter presenter;
private ListType listType;
private List<Event> events;
private RecyclerView recyclerView;
public static EventListFragment newInstance(ListType listType) {
EventListFragment f = new EventListFragment();
Bundle args = new Bundle();
args.putSerializable("listType", listType);
f.setArguments(args);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(com.tractrac.androidlib.R.layout.base_list_fragment, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView = (RecyclerView) view.findViewById(com.tractrac.androidlib.R.id.recycler_view);
switch (getListType()) {
case EVENTS:
getPresenter().getEvents();
break;
case CLUBS:
getPresenter().getClubEvents();
break;
}
}
private EventsFragmentPresenter getPresenter() {
if (presenter == null) {
presenter = new EventsFragmentPresenter();
presenter.initialize(this);
}
return presenter;
}
private ListType getListType() {
if (listType == null) {
listType = (ListType) getArguments().getSerializable("listType");
}
return listType;
}
#Override
public void listReady(List<Event> events) {
EventsRecyclerAdapter adapter = new EventsRecyclerAdapter(events, (EventsActivity) getActivity());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
if (getListType() == ListType.EVENTS) {
mLayoutManager.scrollToPosition(getPresenter().getCurrentDayEventIndex(events));
}
this.events = events;
((EventsActivity) getActivity()).hideSpinner();
}
public void filterList(String filterBy) {
if (TextUtils.isEmpty(filterBy)) {
EventsRecyclerAdapter adapter = new EventsRecyclerAdapter(events, (EventsActivity) getActivity());
recyclerView.setAdapter(adapter);
return;
}
List<Event> filteredEvents = new ArrayList<>();
for (Event event : events) {
if (event.getName().toLowerCase().contains(filterBy) || event.getLocation().toLowerCase().contains(filterBy))
filteredEvents.add(event);
}
EventsRecyclerAdapter adapter = new EventsRecyclerAdapter(filteredEvents, (EventsActivity) getActivity());
recyclerView.setAdapter(adapter);
}
}
In onPageScrollStateChanged you are calling filterList where you are creating a new EventsRecyclerAdaptereach time which is the cause of scroll state being reset.
You should set the adapter once to your RecyclerView and later call notify methods.

Issue viewing Fragment through tabs

I've tried to post a similar questions without any answer, though of posting again.
The issue I am having is with viewing Fragment through Tabs, I have 3 Tabs in an AppBar displayed with ViewPager & FragmentPagerAdapter.
The problem is when the activity start, one of the tabs does not behave in a consistent way, upon logging in to the app & activity for the first time it would display the content of the Fragment ( Video clips ) but during switching between activities in the app, and going back to the Activity containing the 3 Tabs, choosing that specific Tab does not display anything, althou in the Logcat, i could tell it is retrieving Data related to the Vid Clip that should be displayed, also going back that Activity i see in the Logcat that even when i choose a different Tab, ( pictures ) Data from the 2 others Tab is being retrieved !?
The setup is as follows;
Main activity;
public class Member extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.member);
Firebase.setAndroidContext(this);
ButterKnife.bind(this);
// Adding Toolbar to Main screen
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Setting ViewPager for each Tabs
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
// Set Tabs inside Toolbar
TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new PicContentMMFragment(), "Pictures");
adapter.addFragment(new VidContentFragment(), "Videos");
adapter.addFragment(new LocationsContentFragment(), "Locations");
viewPager.setAdapter(adapter);
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public Adapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Well, as one of the users commented on the post pointed out that the problem could be from the specific fragemnt itself and not the way Tabs and Viewpager following is the VidContentFragment;
public class VidContentFragment extends android.support.v4.app.Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final RecyclerView recyclerView = (RecyclerView) inflater.inflate(
R.layout.recycler_view, container, false);
Log.i("MyTag_onCreate","vidContentFragment_Loaded");
ContentAdapter adapter = new ContentAdapter(recyclerView.getContext());
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return recyclerView;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public VideoView video;
public TextView authorName;
public TextView ratingValue;
public TextView locationValue;
public RatingBar ratingB;
public Button submitRating;
public LinearLayout placeNameHolder;
public int newRating;
public ViewHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.item_card_vid, parent, false));
authorName = (TextView) itemView.findViewById(R.id.card_title);
ratingValue = (TextView) itemView.findViewById(R.id.ratingValue);
locationValue = (TextView) itemView.findViewById(R.id.locationValue);
video = (VideoView) itemView.findViewById(R.id.placeVid);
ratingB = (RatingBar)itemView.findViewById(R.id.ratingBarMM);
ratingB.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
#Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
newRating = (int) ratingB.getRating();
}
});
submitRating = (Button) itemView.findViewById(R.id.submitRatingMM);
submitRating.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
public_id = publicID[getPosition()];
Log.i("MyTag_Rating",public_id);
public static class ContentAdapter extends RecyclerView.Adapter<ViewHolder> {
// Set numbers of List in RecyclerView.
private Context mContext;
public ContentAdapter(Context context) {
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.authorName.setText(author[position]);
holder.ratingValue.setText(ratingV[position]);
holder.locationValue.setText(locationV[position]);
Uri video = Uri.parse(mVideos[position]);
holder.video.setVideoURI(video);
holder.video.setMediaController(new MediaController(mContext));
holder.video.requestFocus();
holder.video.seekTo(1000);
holder.video.pause();
try{
String url1 = mVideos[position];
URL ulrn = new URL(url1);
HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
InputStream is = con.getInputStream();
Bitmap bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
Palette.generateAsync(bmp, new Palette.PaletteAsyncListener() {
public void onGenerated(Palette palette) {
int bgColor = palette.getVibrantColor(mContext.getResources().getColor(android.R.color.black));
holder.placeNameHolder.setBackgroundColor(bgColor);
}
});
else
Log.e("MyTag_BMP","The Bitmap is NULL");
}catch (Exception e){
}
}
#Override
public int getItemCount() {
return LENGTH;
}
}
}
Some part of the code (related to retrieving data from firebase) is left out to shorten it.
Although the other 2 fragments are organized the same way, the behavior of this fragment is inconsistent ?
Here is the version of the adapter with viewholder that I have for a recyclerview you said would likely be helpful. You'll need to refactor to adjust for your situation. I have gutted it mostly to help show just the bare interactions.
public class AnimalAdapter extends RecyclerView.Adapter<AnimalAdapter.AnimalCardViewHolder>{
private List<Animals> animalList;
public AnimalAdapter adapter = this;
Context context;
public AnimalAdapter(List<Animals> animalList, Context context) {
this.animalList = animalList;
this.context = context;
this.setInterface((iAdapterInterface) context);
}
#Override
public int getItemCount() {
return animalList.size();
}
#Override
public void onBindViewHolder(AnimalCardViewHolder holder, int position) {
Animals animal = animalList.get(position);
holder.txtName.setText(animal.getName());
holder.txtType.setText(animal.getType());
}
#Override
public AnimalCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.animal_card_view, parent, false);
return new AnimalCardViewHolder(itemView);
}
public class AnimalCardViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
protected TextView txtName;
protected TextView txtType;
public AnimalCardViewHolder(final View itemView) {
super(itemView);
txtName = (TextView) itemView.findViewById(R.id.txtName);
txtType = (TextView) itemView.findViewById(R.id.txtType);
imgClose = (ImageView) itemView.findViewById(R.id.txtRemove);
listItem = itemView.findViewById(R.id.list_item);
listItem.setOnClickListener(this);
imgClose.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.txtRemove:
break;
case R.id.list_item:
break;
}
}
}
}

How to sort list in RecyclerView which is been populated through ViewPager

I have a fragment(say X) which contain ViewPager and TabLayout and i am passing a fragment((say Y)with a list) three times to adapter of this viewpager but every time list is sorted by some parameter.
Y fragment contain RecyclerView. And i am passing that list to the adapter of this RecyclerView.
I am able to populate all the 3 tabs with fragment.But list inside recyclerview is not sorted.Only last tab with recyclerview was comming sorted
Please help me to find shortcoming of the code.
X Fragment
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = getLayoutInflater(savedInstanceState).inflate(R.layout.available_bus_fragment, null);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
List<Bus> departureTimeList = mBusList;
Collections.sort(departureTimeList, new Comparator<Bus>() {
#Override
public int compare(Bus lhs, Bus rhs) {
return lhs.getDepartureTime().compareTo(rhs.getDepartureTime());
}
});
Fragment departureFragment = new AvailableRecyclerViewFragment(departureTimeList);
if (getArguments()!= null) {
departureFragment.setArguments(getArguments());
}
adapter.addFragment(departureFragment, "Departure");
List<Bus> durationTimeList = mBusList;
Collections.sort(durationTimeList, new Comparator<Bus>() {
#Override
public int compare(Bus lhs, Bus rhs) {
return lhs.getDurationForSorting() - rhs.getDurationForSorting();
}
});
Fragment durationFragment = new AvailableRecyclerViewFragment(durationTimeList);
if (getArguments() != null) {
durationFragment.setArguments(getArguments());
}
adapter.addFragment(durationFragment, "Duration");
List<Bus> priceList = mBusList;
Collections.sort(priceList, new Comparator<Bus>() {
#Override
public int compare(Bus lhs, Bus rhs) {
return lhs.getFares() - rhs.getFares();
}
});
Fragment priceFragment = new AvailableRecyclerViewFragment(priceList);
if (getArguments()!= null) {
priceFragment.setArguments(getArguments());
}
adapter.addFragment(priceFragment, "Fare");
viewPager.setAdapter(adapter);
adapter.notifyDataSetChanged();
tabLayout.setupWithViewPager(viewPager);
return rootView;
}
This is my adapter of viewpager.
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragments = new ArrayList();
private final List<String> mFragmentTitles = new ArrayList();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
Y fragment (AvailableRecyclerViewFragment.java)
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = getLayoutInflater(savedInstanceState).inflate(R.layout.available_list_fragment, null);
recycler_view = (RecyclerView) rootView.findViewById(R.id.recycler_view);
adapter = new CustomRecyclerViewAdapter(getActivity(), mBusList);
adapter.notifyDataSetChanged();
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recycler_view.setLayoutManager(mLayoutManager);
recycler_view.setItemAnimator(new DefaultItemAnimator());
recycler_view.setHasFixedSize(true);
recycler_view.setAdapter(adapter);
return rootView;
}
Adapter for Recyclerview
public class CustomRecyclerViewAdapter extends RecyclerView.Adapter<CustomRecyclerViewAdapter.CustomViewHolder> {
private List<Bus> dataList;
Context mContext;
public CustomRecyclerViewAdapter(Context context, List<Bus> list) {
dataList = list;
mContext = context;
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView tv_departureTime;
public TextView tv_arrivalTime;
public TextView tv_duration;
public TextView tv_price;
public TextView tv_availableSeats;
public TextView tv_travels;
public TextView tv_busType;
public CustomViewHolder(View view) {
super(view);
tv_departureTime = (TextView) view.findViewById(R.id.tv_departureTime);
tv_arrivalTime = (TextView) view.findViewById(R.id.tv_arrivalTime);
tv_duration = (TextView) view.findViewById(R.id.tv_duration);
tv_price = (TextView) view.findViewById(R.id.tv_price);
tv_availableSeats = (TextView) view.findViewById(R.id.tv_availableSeats);
tv_travels = (TextView) view.findViewById(R.id.tv_travels);
tv_busType = (TextView) view.findViewById(R.id.tv_busType);
}
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_list_row, parent, false);
final Animation anim = AnimationUtils.loadAnimation(mContext, android.R.anim.slide_in_left);
itemView.setAnimation(anim);
return new CustomViewHolder(itemView);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
Bus bus = dataList.get(position);
holder.tv_arrivalTime.setText("" + bus.getArrivalTime());
String[] data = bus.getDuration().split(":");
holder.tv_departureTime.setText("" + bus.getDepartureTime());
holder.tv_duration.setText("" + data[0] + "hr " + data[1] + "min");
if (bus.getFareList() != null) {
String fare = "";
for (FareDetails tempFare : bus.getFareList()) {
fare = fare + tempFare.getTotalFare() + ("/");
}
holder.tv_price.setText("" + fare.substring(0, fare.length() - 1).toString());
} else {
holder.tv_price.setText("" + bus.getFares());
}
holder.tv_availableSeats.setText("" + bus.getAvailableSeats() + " seats");
holder.tv_travels.setText(bus.getTravels());
holder.tv_busType.setText(bus.getBusType());
}
#Override
public int getItemCount() {
return dataList.size();
}
}
inside of Fragment X(where your ViewPager is) call method setOnPageChangeListener:
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
viewPagerAdapter.notifyDataSetChanged();
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
As you see inside of onPageSelected() call notifyDataSetChanged for your viewpager adapter. Then it should sort fragment that you're on.

Categories

Resources