In my app I have four layouts, "Card List" , "Card Magazine" , "Title" and "Grid", I make option menu to allow the users to change it from the Option Menu "change the layout", the problem happening here is when running the app first time with choosing Title or Grid layout, it's show the only first page "10 items" the result come from retrofit call
To relate see this question
in old version of this app "When I used activity" I solved this problem with this lines of code on Title and Grid Viewholder
if(position == getItemCount() -1)
if(context instanceof MainActivity){
((MainActivity)context).getMainPagePosts();
}
but in this version I using fragments, so when I tried to thinking to solve it I created interface called "WhichFragmentCalled" and give it the fragment and viewHolder as a parameters
public interface WhichFragmentCalled {
void whichFragmentAndViewModel(Fragment fragment, PostViewModel postViewModel);
}
Then I used it in adapter and fragment like this
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
WhichFragmentCalled whichFragmentCalled = adapter;
whichFragmentCalled.whichFragmentAndViewModel(this,postViewModel);
}
and make the adapter implement this interface, here's the full PostAdapter code
public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements WhichFragmentCalled{
private Context context;
private List<Item> items;
private static final int CARD = 0;
private static final int CARD_MAGAZINE = 1;
private static final int TITLE = 2;
private static final int GRID = 3;
private static final int SDK_VERSION = Build.VERSION.SDK_INT;
public static final String TAG = "POST ADAPTER";
private int viewType;
private int position;
private Fragment fragment;
private PostViewModel postViewModel;
public PostAdapter(Context context, List<Item> items) {
this.context = context;
this.items = items;
}
public void setViewType(int viewType) {
this.viewType = viewType;
notifyDataSetChanged();
}
public int getViewType() {
return this.viewType;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view;
if (this.viewType == CARD) {
view = inflater.inflate(R.layout.card, parent, false);
return new CardViewHolder(view);
} else if (this.viewType == CARD_MAGAZINE) {
view = inflater.inflate(R.layout.card_magazine, parent, false);
return new CardMagazineViewHolder(view);
} else if (this.viewType == TITLE) {
if(SDK_VERSION < Build.VERSION_CODES.LOLLIPOP){
view = inflater.inflate(R.layout.title_layout_v15,parent,false);
}else {
view = inflater.inflate(R.layout.title_layout, parent, false);
}
return new TitleViewHolder(view);
} else {
if(SDK_VERSION < Build.VERSION_CODES.LOLLIPOP){
view = inflater.inflate(R.layout.grid_layout_v15,parent,false);
}else {
view = inflater.inflate(R.layout.grid_layout, parent, false);
}
return new GridViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
this.position = position;
int itemType = getViewType();
Item item = items.get(holder.getAdapterPosition());
final Document document = Jsoup.parse(item.getContent());
final Elements elements = document.select("img");
// Log.e("IMAGE", document.getAllElements().select("img").get(0).attr("src"));
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat
("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
Intent intent = new Intent(context, DetailsActivity.class);
switch (itemType) {
case CARD:
if (holder instanceof CardViewHolder) {
CardViewHolder cardViewHolder = (CardViewHolder) holder;
cardViewHolder.postTitle.setText(item.getTitle());
try {
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(cardViewHolder.postImage);
}catch (IndexOutOfBoundsException e){
cardViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
}
cardViewHolder.postDescription.setText(document.text());
try {
date = format.parse(items.get(position).getPublished());
} catch (ParseException e) {
e.printStackTrace();
}
PrettyTime prettyTime = new PrettyTime();
cardViewHolder.postDate.setText(prettyTime.format(date));
cardViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility = 0;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video")) {
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
}
if (youtubeThumbnailImageSrc.isEmpty()) {
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
} else {
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
}
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
}
});
}
break;
case CARD_MAGAZINE:
if (holder instanceof CardMagazineViewHolder) {
CardMagazineViewHolder cardMagazineViewHolder = (CardMagazineViewHolder) holder;
cardMagazineViewHolder.postTitle.setText(item.getTitle());
try {
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(cardMagazineViewHolder.postImage);
}catch (IndexOutOfBoundsException e){
cardMagazineViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
}
try {
date = format.parse(items.get(position).getPublished());
} catch (ParseException e) {
e.printStackTrace();
}
PrettyTime prettyTime = new PrettyTime();
cardMagazineViewHolder.postDate.setText(prettyTime.format(date));
cardMagazineViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility = 0;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video")) {
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
}
if (youtubeThumbnailImageSrc.isEmpty()) {
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
} else {
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
}
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
}
});
}
break;
case TITLE:
if (holder instanceof TitleViewHolder) {
TitleViewHolder titleViewHolder = (TitleViewHolder) holder;
titleViewHolder.postTitle.setText(item.getTitle());
Log.d("TITLE", "title layout called");
try {
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(titleViewHolder.postImage);
}catch (IndexOutOfBoundsException e){
titleViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
}
titleViewHolder.itemView.setOnClickListener(view -> {
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility = 0;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video")) {
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
}
if (youtubeThumbnailImageSrc.isEmpty()) {
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
} else {
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
}
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
});
}
break;
case GRID:
if (holder instanceof GridViewHolder) {
GridViewHolder gridViewHolder = (GridViewHolder) holder;
gridViewHolder.postTitle.setText(item.getTitle());
try {
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(gridViewHolder.postImage);
}catch (IndexOutOfBoundsException e){
gridViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
}
gridViewHolder.itemView.setOnClickListener(view -> {
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video")) {
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
}
if (youtubeThumbnailImageSrc.isEmpty()) {
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
} else {
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
}
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
});
}
}
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public void whichFragmentAndViewModel(Fragment fragment, PostViewModel postViewModel) {
this.fragment = fragment;
this.postViewModel = postViewModel;
if(position == getItemCount() -1) {
postViewModel.getPosts();
notifyDataSetChanged();
}
}
public class CardViewHolder extends RecyclerView.ViewHolder {
ImageView postImage;
TextView postTitle,postDescription, postDate;
private CardViewHolder(View itemView) {
super(itemView);
postImage = itemView.findViewById(R.id.postImage);
postTitle = itemView.findViewById(R.id.postTitle);
postDescription = itemView.findViewById(R.id.postDescription);
postDate = itemView.findViewById(R.id.postDate);
}
}
public class CardMagazineViewHolder extends RecyclerView.ViewHolder {
ImageView postImage;
TextView postTitle, postDate;
private CardMagazineViewHolder(View itemView) {
super(itemView);
postImage = itemView.findViewById(R.id.postImage);
postTitle = itemView.findViewById(R.id.postTitle);
postDate = itemView.findViewById(R.id.postDate);
}
}
public class TitleViewHolder extends RecyclerView.ViewHolder {
TextView postTitle;
MyImageview postImage;
private TitleViewHolder(@NonNull View itemView) {
super(itemView);
postTitle = itemView.findViewById(R.id.postTitle);
postImage = itemView.findViewById(R.id.postImage);
}
}
public class GridViewHolder extends RecyclerView.ViewHolder {
TextView postTitle;
MyImageview postImage;
private GridViewHolder(@NonNull View itemView) {
super(itemView);
postTitle = itemView.findViewById(R.id.postTitle);
postImage = itemView.findViewById(R.id.postImage);
}
}
}
now this code work only when I switch from the title or grid layout to others layout and back to it again, I think the onBindViewHolder not detect this implement of interface at the first time, so the challenge is How to move the implement of this interface insede onBindViewHolder method
@Override
public void whichFragmentAndViewModel(Fragment fragment, PostViewModel postViewModel) {
this.fragment = fragment;
this.postViewModel = postViewModel;
if(position == getItemCount() -1) {
postViewModel.getPosts();
notifyDataSetChanged();
}
}
This how I use the change layout in fragments, I removed unrelated with question codes
HomeFragment class
private PostViewModel postViewModel;
public static final String TAG = "HomeFragment";
private RecyclerView recyclerView;
private PostAdapter adapter;
private List<Item> itemArrayList;
private boolean isScrolling = false;
private int currentItems, totalItems, scrollOutItems;
private GridLayoutManager titleLayoutManager, gridLayoutManager;
WrapContentLinearLayoutManager layoutManager;
private SharedPreferences sharedPreferences;
public ItemsDatabase itemsDatabase;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
postViewModel = new ViewModelProvider(this).get(PostViewModel.class);
itemsDatabase = ItemsDatabase.getINSTANCE(getContext());
postViewModel.finalURL.setValue(PostsClient.getBaseUrl() + "?key=" + PostsClient.getKEY() );
postViewModel.getPosts();
View root = inflater.inflate(R.layout.fragment_home, container, false);
setHasOptionsMenu(true);
itemArrayList = new ArrayList<>();
recyclerView = root.findViewById(R.id.homeRecyclerView);
adapter = new PostAdapter(getContext(),itemArrayList);
layoutManager = new WrapContentLinearLayoutManager(getContext(),
LinearLayoutManager.VERTICAL, false);
titleLayoutManager = new GridLayoutManager(getContext(), 2);
gridLayoutManager = new GridLayoutManager(getContext(), 3);
sharedPreferences = getContext().getSharedPreferences("settings", Context.MODE_PRIVATE);
String layout = sharedPreferences.getString("recyclerViewLayout", "cardLayout");
switch (layout) {
case "cardLayout":
recyclerView.setLayoutManager(layoutManager);
adapter.setViewType(0);
recyclerView.setAdapter(adapter);
break;
case "cardMagazineLayout":
recyclerView.setLayoutManager(layoutManager);
adapter.setViewType(1);
recyclerView.setAdapter(adapter);
break;
case "titleLayout":
recyclerView.setLayoutManager(titleLayoutManager);
adapter.setViewType(2);
recyclerView.setAdapter(adapter);
adapter.whichFragmentAndViewModel(this,postViewModel);
break;
case "gridLayout":
recyclerView.setLayoutManager(gridLayoutManager);
adapter.setViewType(3);
recyclerView.setAdapter(adapter);
adapter.whichFragmentAndViewModel(this,postViewModel);
}
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
isScrolling = true;
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
if(layout.equals("cardLayout") || layout.equals("cardMagazineLayout")) {
currentItems = layoutManager.getChildCount();
totalItems = layoutManager.getItemCount();
scrollOutItems = layoutManager.findFirstVisibleItemPosition();
}else if(layout.equals("titleLayout")){
currentItems = titleLayoutManager.getChildCount();
totalItems = titleLayoutManager.getItemCount();
scrollOutItems = titleLayoutManager.findFirstCompletelyVisibleItemPosition();
}else {
currentItems = gridLayoutManager.getChildCount();
totalItems = gridLayoutManager.getItemCount();
scrollOutItems = gridLayoutManager.findFirstCompletelyVisibleItemPosition();
}
if (isScrolling && (currentItems + scrollOutItems == totalItems)) {
isScrolling = false;
postViewModel.getPosts();
// adapter.notifyDataSetChanged();
}
}
}
});
return root;
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
//Empty the old menu
// if(menu.hasVisibleItems()){
// menu.clear();
// }
inflater.inflate(R.menu.main, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.change_layout) {
android.app.AlertDialog.Builder builder
= new android.app.AlertDialog.Builder(getContext());
builder.setTitle(getString(R.string.choose_layout));
String[] recyclerViewLayouts = getResources().getStringArray(R.array.RecyclerViewLayouts);
SharedPreferences.Editor editor = sharedPreferences.edit();
builder.setItems(recyclerViewLayouts, (dialog, index) -> {
switch (index) {
case 0: // Card List Layout
adapter.setViewType(0);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "cardLayout");
editor.apply();
break;
case 1: // Cards Magazine Layout
adapter.setViewType(1);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "cardMagazineLayout");
editor.apply();
break;
case 2: // PostTitle Layout
adapter.setViewType(2);
recyclerView.setLayoutManager(titleLayoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "titleLayout");
editor.apply();
break;
case 3: //Grid Layout
adapter.setViewType(3);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "gridLayout");
editor.apply();
}
});
android.app.AlertDialog alertDialog = builder.create();
alertDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
WhichFragmentCalled whichFragmentCalled = adapter;
whichFragmentCalled.whichFragmentAndViewModel(this,postViewModel);
}
}
from How to fill title and grid layouts with the next page "10 items"

No comments:
Post a Comment