I am working in project that I use Tablayout inside fragment , I have three tabs where they fetch data from web service , this part of the app show questions , we have three categories one for recent , second for un answered third for all question view
here is my situation my web developer design me web service return question item , they all share the same structure in returned item but data changed according to requirement .
public class Questions_Fragment extends Fragment {
private TabLayout mTablayout;
private ViewPager mViewpager;
public static Questions_Fragment newInstance() {
Questions_Fragment fragment = new Questions_Fragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.questions_layout, null);
mViewpager = (ViewPager) v.findViewById(R.id.viewPager);
setupViewPager(mViewpager);
mTablayout = (TabLayout) v.findViewById(R.id.tabs);
mTablayout.setupWithViewPager(mViewpager);
return v;
}
private void setupViewPager(ViewPager mViewpager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFrag( QuestionsFragModel.newInstance(VolleyRequestHandler.RECENT_INT) , getResources().getString(R.string.newest));
adapter.addFrag( QuestionsFragModel.newInstance(VolleyRequestHandler.UNANSWER_INT) , getResources().getString(R.string.notanswered));
adapter.addFrag( QuestionsFragModel.newInstance(VolleyRequestHandler.ALLPOSTS_INT) , getResources().getString(R.string.allposts));
mViewpager.setAdapter(adapter);
}
my view pager adapter class I extend FragmentStatePagerAdapter data could change each time user open tab
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragmentList = new ArrayList<>();
private List<String> mFragmentTitleList= new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fra , String title){
mFragmentList.add(fra);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
but I see it give me wrong view, it show image in question dont have image and it give answer to unanswered question
sorry for my long question but I want know what is wrong with my code ??
my list adapter
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder> {
private Context _Context;
private List<QuestionItem> Questions = new ArrayList<>();
private API api;
private int num;
private int lastPosition = -1;
public static final String BASE_POST_URl = "url....";
public ListViewAdapter(Context context, List<QuestionItem> Questions) {
this._Context = context;
this.Questions = Questions;
api = new API(context);
}
public ListViewAdapter(Context context, List<QuestionItem> Questions,
int num) {
this._Context = context;
this.Questions = Questions;
this.num = num;
api = new API(context);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(_Context);
View itemView = inflater.inflate(R.layout.question_row, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
Typeface tf = Typeface.createFromAsset(_Context.getAssets(),
"fonts/GE_SS_Two_Bold.otf");
Typeface tfreg = Typeface.createFromAsset(_Context.getAssets(),
"fonts/GE_SS_Two_Light.otf");
ImageLoader _ImageLoader = MySingleton.getInstance(_Context).getmImageLoader();
if (Questions.get(position).user.userimageURL != null) {
if (!Questions.get(position).user.getUserimageURL().isEmpty()) {
//holder.userimageprog.setVisibility(View.VISIBLE);
holder.imageView.setImageUrl(Profile_Fragment.BASE_URL + Questions.get(position).user.getUserimageURL(), _ImageLoader);
}
}
if(Questions.get(position).Que_image_url != null){
if (!Questions.get(position).getQue_image_url().isEmpty()) {
holder._FrameLayout.setVisibility(View.VISIBLE);
holder.post_img.setVisibility(View.VISIBLE);
//holder.post_img_pro.setVisibility(View.VISIBLE);
holder.post_img.setImageUrl(BASE_POST_URl + Questions.get(position).getQue_image_url(), _ImageLoader);
}
}
holder.imageView.setDefaultImageResId(R.drawable.profile);
holder.username.setTypeface(tf);
holder.desc.setTypeface(tfreg);
holder.Date.setTypeface(tfreg);
holder.AnswersCount.setTypeface(tfreg);
if(Questions.get(position).user.username != null){
holder.username.setText(Questions.get(position).user.username);
}
if(Questions.get(position).Que_Content != null){
holder.desc.setText(Questions.get(position).Que_Content);
}
if(Questions.get(position).category != null){
holder.Category.setText(Questions.get(position).category);
}
if(Questions.get(position).Que_Date != null){
holder.Date.setText(Questions.get(position).Que_Date);
}
if (!Questions.get(position).getComment().isEmpty()) {
holder.arrow.setVisibility(View.VISIBLE);
holder.AnswersCount.setVisibility(View.VISIBLE);
holder.AnswersCount.setText(_Context.getResources().getString(R.string.youhaveanswer));
}
holder.arrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent (_Context , ViewAnswers.class);
intent.putExtra("passedobject", (Parcelable) Questions.get(position));
_Context.startActivity(intent);
}
});
// Animation animation = null;
// animation = AnimationUtils.loadAnimation(_Context,
// R.anim.up_from_bottom);
// animation.setDuration(500);
// view.setAnimation(animation);
// animation = null;
//
// Animation animation = AnimationUtils.loadAnimation(_Context,
// (pos > lastPosition) ? R.anim.up_from_bottom
// : R.anim.down_from_top);
// view.startAnimation(animation);
// lastPosition = pos;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
return Questions.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
protected NetworkImageView imageView, post_img;
protected TextView desc, Category, username, Date, AnswersCount;
protected ProgressBar userimageprog, post_img_pro;
protected ImageView arrow;
protected FrameLayout _FrameLayout;
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.ques_user_img);
desc = (TextView) itemView.findViewById(R.id.ques_content);
Category = (TextView) itemView.findViewById(R.id.category);
post_img = (NetworkImageView) itemView.findViewById(R.id.post_img);
userimageprog = (ProgressBar) itemView.findViewById(R.id.userimgae_prog);
post_img_pro = (ProgressBar) itemView.findViewById(R.id.post_prog);
username = (TextView) itemView.findViewById(R.id.username_ques);
Date = (TextView) itemView.findViewById(R.id.date);
AnswersCount = (TextView) itemView.findViewById(R.id.answers_con);
arrow = (ImageView) itemView.findViewById(R.id.imageView1);
_FrameLayout = (FrameLayout)itemView.findViewById(R.id.frameLayout2);
}
}
}
QuestionsFragModel view
public class QuestionsFragModel extends Fragment implements OnClickListener {
private RecyclerView Ques_list;
private ProgressBar list_prog;
private ListViewAdapter adapter;
private List<QuestionItem> Questions = new ArrayList<>();
private TextView reload;
private VolleyRequestHandler _VolleyRequestHandler;
private int CONST_TYPE = 0;
public static final String PASSED_INT = "passed_number";
private CoordinatorLayout _coordiatelayout;
static QuestionsFragModel newInstance(int type) {
QuestionsFragModel f = new QuestionsFragModel();
Bundle bundle = new Bundle();
bundle.putInt(PASSED_INT , type);
f.setArguments(bundle);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.question_layout, container, false);
CONST_TYPE = getArguments() != null ? getArguments().getInt(PASSED_INT) : 7;
_VolleyRequestHandler = new VolleyRequestHandler(getActivity());
_coordiatelayout = (CoordinatorLayout) v.findViewById(R.id.coordiatelayout);
Ques_list = (RecyclerView) v.findViewById(R.id.questionlist);
Ques_list.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new ListViewAdapter(getActivity(), Questions);
Ques_list.setAdapter(adapter);
list_prog = (ProgressBar) v.findViewById(R.id.progressbar);
reload = (TextView) v.findViewById(R.id.reload);
getQuestationsPosts();
reload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View position) {
getQuestationsPosts();
}
});
final FloatingActionButton floatingView = (FloatingActionButton) v.findViewById(R.id.FloatingView);
if (floatingView != null) {
floatingView.setOnClickListener(this);
}
return v;
}
public void getQuestationsPosts() {
API api = new API(getActivity());
if (api.isNetworkConnected()) {
list_prog.setVisibility(View.VISIBLE);
reload.setVisibility(View.GONE);
FetchQuestationsFromWeb();
} else {
Snackbar.make(_coordiatelayout, getResources().getString(R.string.nointernet), Snackbar.LENGTH_LONG).show();
Ques_list.setVisibility(View.GONE);
reload.setVisibility(View.VISIBLE);
}
}
private void onSuccessResponse(Object response){
list_prog.setVisibility(View.GONE);
reload.setVisibility(View.GONE);
Ques_list.setVisibility(View.VISIBLE);
if(Questions != null){
Questions.clear();
}
Questions = (List < QuestionItem>) response;
adapter = new ListViewAdapter(getActivity() ,Questions);
Ques_list.setAdapter(adapter);
}
private void onErrorResponse(String error){
list_prog.setVisibility(View.GONE);
reload.setVisibility(View.VISIBLE);
Snackbar.make(_coordiatelayout , error , Snackbar.LENGTH_LONG).show();
}
private void FetchQuestationsFromWeb() {
_VolleyRequestHandler.HandleRequests(Request.Method.POST , CONST_TYPE, null, new VolleyResponseCallBack() {
#Override
public void RequestSuccess(Object response) {
onSuccessResponse(response);
}
#Override
public void RequestFailed(String error) {
onErrorResponse(error);
}
});
}
#Override
public void onClick(View arg0) {
startActivity(new Intent(getActivity(), Add_Question.class));
}
}
I don't know why you use FragmentStatePagerAdapter instead of FragmentPagerAdapter when you have only 3 fragments.
AFAIK, FragmentStatePagerAdapter is better for performance if you have a large amount of fragments, because it don't stores the whole fragment in memory.
Anyway, FragmentStatePagerAdapter will save out your fragment's Bundle from savedInstanceState when it is destroyed. And when the user navigates back, the new fragment will be restored using the fragment's state.
So you need to check savedInstanceState before:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.question_layout, container, false);
if (savedInstanceState!=null){
// restore your state from "savedInstanceState"
} else{
CONST_TYPE = getArguments() != null ? getArguments().getInt(PASSED_INT) : 7;
}
}
If someone face some issue, it cause of I use if statement in adapter , simply you can use if only without else
Example I use if only
if (Questions.get(position).user.userimageURL != null) {
if (!Questions.get(position).user.getUserimageURL().isEmpty()) {
//holder.userimageprog.setVisibility(View.VISIBLE);
holder.imageView.setImageUrl(Profile_Fragment.BASE_URL + Questions.get(position).user.getUserimageURL(), _ImageLoader);
}
} else{
// I should use else statement as well
}
Related
I have a recycleview which fetches data from api with a custom adapter containing a textview and imageview and I implemented this in Activity and it works fine, but now I tried to use fragment instead of activity and every thing works fine except for the images that are not displayed after moving the code to fragment so this is my fragment:
public class TVFragment extends Fragment implements TVAdapter.TVAdapterOnClickHandler {
TVAdapter mAdapter;
RecyclerView mSportsList;
String sortsports="sports.php";
Context mContext ;
public static TVFragment newInstance() {
TVFragment fragment = new TVFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tv, container, false);
mSportsList = (RecyclerView) view.findViewById(R.id.rv_sports);
mContext = getActivity();
GridLayoutManager LayoutManagerSports = new GridLayoutManager(getActivity(), 3);
mSportsList.setLayoutManager(LayoutManagerSports);
mSportsList.setHasFixedSize(true);
mAdapter = new TVAdapter(this, mContext);
mSportsList.setAdapter(mAdapter);
loadTVData(sortsports);
return view;
}
private void loadTVData(String sortChannels) {
showTVDataView();
new FetchTVTask().execute(sortChannels);
}
#Override
public void onClick(TVItem channel) {
Context context = getActivity().getApplicationContext();
Class destinationClass = TVChannel.class;
Intent intentToStartDetailActivity = new Intent(context, destinationClass);
intentToStartDetailActivity.putExtra("TVChannel", channel);
startActivity(intentToStartDetailActivity);
}
private void showTVDataView() {
mSportsList.setVisibility(View.VISIBLE);
}
public class FetchTVTask extends AsyncTask<String, Void, ArrayList<TVItem>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected ArrayList<TVItem> doInBackground(String... params) {
if (params.length == 0) {
return null;
}
String sortChannels = params[0];
URL channelRequestUrl = NetworkTV.buildUrl(sortChannels);
try {
String jsonTVResponse = NetworkTV.getResponseFromHttpUrl(channelRequestUrl);
ArrayList<TVItem> simpleJsonTVData = JsonTV.getSimpleTVStringsFromJson(getContext(), jsonTVResponse);
return simpleJsonTVData;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(ArrayList<TVItem> TVData) {
if (TVData != null) {
showTVDataView();
mAdapter.setTVData(TVData);
} else {
}
}
}
}
then this is my adapter:
public class TVAdapter extends RecyclerView.Adapter<TVAdapter.RecyclerViewHolder> {
ArrayList<TVItem> mChannelItems;
private Context mContext;
private final TVAdapter.TVAdapterOnClickHandler mClickHandler;
public interface TVAdapterOnClickHandler {
void onClick(TVItem channel);
}
public TVAdapter(TVAdapterOnClickHandler clickHandler, Context context) {
this.mContext = context;
mClickHandler = clickHandler;
}
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView Cat;
public final ImageView Image;
public RecyclerViewHolder(View view) {
super(view);
Cat = (TextView)itemView.findViewById(R.id.channel_cat);
Image = (ImageView) itemView.findViewById(R.id.channel_image);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
TVItem channel = mChannelItems.get(adapterPosition);
mClickHandler.onClick(channel);
}
}
#Override
public TVAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
mContext = viewGroup.getContext();
int layoutIdForListItem = R.layout.tv_list_item;
LayoutInflater inflater = LayoutInflater.from(mContext);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new TVAdapter.RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(TVAdapter.RecyclerViewHolder holder, int position) {
Picasso.with(mContext).load(mChannelItems.get(position).getFullImagePath()).resize(500,500).placeholder(R.drawable.placeholder).error(R.drawable.placeholder).into(holder.Image);
holder.Cat.setText(String.valueOf(mChannelItems.get(position).getTitle()));
}
#Override
public int getItemCount() {
if (null == mChannelItems)
return 0;
else {
return mChannelItems.size();
}
}
public void setTVData(ArrayList<TVItem> TVData) {
mChannelItems = TVData;
notifyDataSetChanged();
}
}
you can see these lines:
Picasso.with(mContext).load(mChannelItems.get(position).getFullImagePath()).resize(500,500).placeholder(R.drawable.placeholder).error(R.drawable.placeholder).into(holder.Image);
and:
holder.Cat.setText(String.valueOf(mChannelItems.get(position).getTitle()));
the cat still displayed well in textview but the images with picasso library not displayed anymore and I read a lot of solutions like pass the context from fragment to adapter but nothing work!
this is the debugging images:
viewgroup.getContext() Isn't the context needed, but the context from the fragment or an activity.
#Override
public TVAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
//mContext = viewGroup.getContext(); This should fix it. You already init mContext in the constructor.
int layoutIdForListItem = R.layout.tv_list_item;
LayoutInflater inflater = LayoutInflater.from(mContext);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new TVAdapter.RecyclerViewHolder(view);
}
Why are you assigning value to mContext twice? Try removing mContext = viewGroup.getContext(); from code.
I want to click an item on the RecyclerView (on a list fragment) and then go to the detail fragment with some data of the item.
I already knew how to use intent in activity, but I cannot find example to do with RecyclerView item.
//In first Activity
Intent intent = new Intent();
intent.setClass(this,SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putDouble("height",height);
bundle.putString("sex",sex);
intent.putExtras(bundle);
startActivity(intent);
//In second Activity
Bundle bundle1=this.getIntent().getExtras();
String sex=bundle1.getString("sex");
double height=bundle1.getDouble("height");
I am stuck in Adapter. Can anyone explain to me step by step?
Thanks!
My adapter code
public class GPAAdapter extends RecyclerView.Adapter<GPAAdapter.ViewHolder> {
private List<GPAModel> mGPAList;
class ViewHolder extends RecyclerView.ViewHolder {
TextView lessonNameText;
TextView lessonCodeText;
TextView teacherNameText;
TextView semesterNameText;
View listView;
public ViewHolder(View gpaItemView) {
super(gpaItemView);
lessonNameText = (TextView) gpaItemView.findViewById(R.id.gpa_lessonName);
lessonCodeText = (TextView) gpaItemView.findViewById(R.id.gpa_lessonCode);
teacherNameText = (TextView) gpaItemView.findViewById(R.id.gpa_teacherName);
semesterNameText = (TextView) gpaItemView.findViewById(R.id.gpa_semesterName);
listView = gpaItemView;
}
}
public GPAAdapter(List<GPAModel> dataList) {
mGPAList = dataList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gpa_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
return holder;
}
public void setData(List<GPAModel> viewData) {
mGPAList.clear();
mGPAList.addAll(viewData);
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
GPAModel data = mGPAList.get(position);
holder.setIsRecyclable(true);
holder.lessonNameText.setText(data.getLessonName());
holder.lessonCodeText.setText(data.getLessonCode());
holder.teacherNameText.setText(data.getTeacherName());
holder.semesterNameText.setText(data.getSemesterName());
//save position in itemView with TAG
holder.itemView.setTag(position);
}
#Override
public int getItemCount() {
return mGPAList.size();
}
//define interface
public static interface OnItemClickListener {
void onItemClick(View view , int position);
}
private OnItemClickListener mOnItemClickListener = null;
//Alert: method does not override method from its superclass
#Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
//getTag of position
mOnItemClickListener.onItemClick(v,(int)v.getTag());
}
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
}
}
My list fragment
private FragmentManager manager;
private FragmentTransaction ft;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View gpaView = inflater.inflate(R.layout.fragment_gpa, container, false);
RecyclerView gpaRecyclerView = (RecyclerView) gpaView.findViewById(R.id.gpa_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
gpaRecyclerView.setLayoutManager(layoutManager);
GPAAdapter adapter = new GPAAdapter(getData());
gpaRecyclerView.setAdapter(adapter);
return gpaView;
//how use .setArguments(bundle) in fragment?
super.onCreate(savedInstanceState);
manager = getFragmentManager();
GPAAdapter.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(View view , int position){
Toast.makeText(MainActivity.this, data[position], 600).show();
}
});
}
private List<GPAModel> getData() {
}
You can replace a fragment using FragmentTransaction in onItemClick in your List Fragment
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.details, new NewFragmentToReplace(), "NewFragmentTag");
ft.commit();
Call getFragmentManager on Recycler.Adapter is a bit hard for me. So I here choose send click message to a new Activity (for detail show).
Hope my code can help somebody.
My adapter code
public class GPAAdapter extends RecyclerView.Adapter<GPAAdapter.ViewHolder> {
private ArrayList<GPAModel> mGPAList;
Context context;
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView lessonNameText;
TextView lessonCodeText;
TextView teacherNameText;
TextView semesterNameText;
View listView;
ArrayList<GPAModel> list = new ArrayList<GPAModel>();
Context ctx;
public ViewHolder(View gpaItemView, Context myCtx, ArrayList<GPAModel> myList) {
super(gpaItemView);
gpaItemView.setOnClickListener(this);
this.list = myList;
this.ctx = myCtx;
lessonNameText = (TextView) gpaItemView.findViewById(R.id.gpa_lessonName);
lessonCodeText = (TextView) gpaItemView.findViewById(R.id.gpa_lessonCode);
teacherNameText = (TextView) gpaItemView.findViewById(R.id.gpa_teacherName);
semesterNameText = (TextView) gpaItemView.findViewById(R.id.gpa_semesterName);
listView = gpaItemView;
}
#Override
public void onClick(View view) {
int position = getAdapterPosition();
GPAModel sendGPA = this.list.get(position);
Intent intent = new Intent(this.ctx, GPADetail.class);
intent.putExtra("lessonName", sendGPA.getLessonName());
intent.putExtra("lessonCode", sendGPA.getLessonCode());
intent.putExtra("creditPoint", sendGPA.getCreditPoint());
intent.putExtra("teacherName", sendGPA.getTeacherName());
intent.putExtra("semesterName", sendGPA.getSemesterName());
intent.putExtra("totalStudentNumber", sendGPA.getTotalStudentNumber());
//
ArrayList<String> scoreValue = new ArrayList<String>();
scoreValue = sendGPA.getScoreValue();
intent.putExtra("scoreValue", scoreValue);
//
ArrayList<Float> studentCount = new ArrayList<Float>();
studentCount = sendGPA.getStudentCount();
intent.putExtra("studentCount",studentCount);
this.ctx.startActivity(intent);
}
}
public GPAAdapter(ArrayList<GPAModel> myList, Context myContext) {
this.mGPAList = myList;
this.context = myContext;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gpa_item, parent, false);
final ViewHolder holder = new ViewHolder(view, context, mGPAList);
return holder;
}
public void setData(List<GPAModel> viewData) {
mGPAList.clear();
mGPAList.addAll(viewData);
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
GPAModel data = mGPAList.get(position);
holder.setIsRecyclable(true);
holder.lessonNameText.setText(data.getLessonName());
holder.lessonCodeText.setText(data.getLessonCode());
holder.teacherNameText.setText(data.getTeacherName());
holder.semesterNameText.setText(data.getSemesterName());
}
#Override
public int getItemCount() {
return mGPAList.size();
}
}
My list fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View gpaView = inflater.inflate(R.layout.fragment_gpa, container, false);
RecyclerView gpaRecyclerView = (RecyclerView) gpaView.findViewById(R.id.gpa_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
gpaRecyclerView.setLayoutManager(layoutManager);
GPAAdapter adapter = new GPAAdapter(getData());
gpaRecyclerView.setAdapter(adapter);
return gpaView;
}
private List<GPAModel> getData() {
}
Then upcast context to AppCompatActivity like this and get the getSupportFragmentManager
FragmentTransaction transaction =((AppCompatActivity) context).getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, new CartLayout()); // Add your fragment class
transaction.addToBackStack(null);
transaction.commit();
I have 2 fragments, both work with array adapter to display their category. First fragment is display item category, second fragment is display job category. However, it display the job category in both fragment. I don't know which part is going wrong.
This is my ViewPager to display the fragment when the user select the corresponding tab. The setCategory() will called when received the data from database.
public class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Category> categoryList = new ArrayList();
private DisplayItemFragment itemFragment;
private DisplayJobFragment jobFragment;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Log.d("categoryList", categoryList.size()+" ");
if (position ==0) {
itemFragment = new DisplayItemFragment(categoryList);
return itemFragment;
}else{
jobFragment = new DisplayJobFragment(categoryList);
return jobFragment;
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
//
//Your tab titles
//
case 0:return "Item";
case 1:return "Job";
default:return null;
}
}
public void setCategory(List<Category> list){
List<Category> tempList = new ArrayList();
for(int i=0;i<list.size();i++){
if(list.get(i).getType().equals("item")){
tempList.add(list.get(i));
}
}
itemFragment.update(tempList);
Log.d("this.categoryListitem",tempList.size()+"");
tempList.clear();
for(int i=0;i<list.size();i++){
if(list.get(i).getType().equals("job")){
tempList.add(list.get(i));
}
}
jobFragment.update(tempList);
Log.d("this.categoryListjob",tempList.size()+"");
}
}
This is the fragment to display item category
public class DisplayItemFragment extends Fragment {
private View rootView;
private GridView gridView;
private List<Category> categoryList;
private DisplayFragmentPresenter presenter;
private CategoryGridAdapter categoryAdapter;
private TextView text;
public DisplayItemFragment(List<Category> categoryList) {
this.categoryList=categoryList;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_display, container, false);
text = (TextView) rootView.findViewById(R.id.test);
categoryAdapter = new CategoryGridAdapter(getActivity(), R.layout.fragment_display, categoryList);
gridView = (GridView) rootView.findViewById(R.id.gridview);
gridView.setAdapter(categoryAdapter);
gridView.setTextFilterEnabled(true);
//Log.d("category",categoryList.get(0).getName());
return rootView;
}
public void update(List<Category> list) {
this.categoryList.clear();
for(int i=0;i<list.size();i++){
if(list.get(i).getType().equals("item")){
this.categoryList.add(list.get(i));
}
}
text.setText("item refresh");
for(int i=0;i<this.categoryList.size();i++){
Log.d("categoryListitem",categoryList.get(i).getName());
}
}
This is the fragment to display job category
public class DisplayJobFragment extends Fragment {
private View rootView;
private GridView gridView;
private List<Category> categoryList;
private DisplayFragmentPresenter presenter;
private TextView text;
private CategoryGridAdapter categoryAdapter;
public DisplayJobFragment(List<Category> categoryList) {
this.categoryList=categoryList;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_display, container, false);
text = (TextView) rootView.findViewById(R.id.test);
categoryAdapter = new CategoryGridAdapter(getActivity(), R.layout.fragment_display, categoryList);
gridView = (GridView) rootView.findViewById(R.id.gridview);
gridView.setAdapter(categoryAdapter);
gridView.setTextFilterEnabled(true);
//Log.d("category",categoryList.get(0).getName());
return rootView;
}
public void update(List<Category> list) {
this.categoryList.clear();
for(int i=0;i<list.size();i++){
if(list.get(i).getType().equals("job")){
this.categoryList.add(list.get(i));
}
}
text.setText("job refresh");
//categoryAdapter = new CategoryGridAdapter(getActivity(), R.layout.fragment_display, this.categoryList);
for(int i=0;i<this.categoryList.size();i++){
Log.d("categoryListjob",categoryList.get(i).getName());
}
}
}
Both fragment will called CategoryGridAdapter to display category on gridview
public class CategoryGridAdapter extends ArrayAdapter<Category> {
private List<Category> categoryList;
private Context context;
public CategoryGridAdapter(Context context, int resource, List<Category> categoryList) {
super(context, resource, categoryList);
this.context = context;
this.categoryList = categoryList;
}
#Override
public boolean isEnabled(int position) {
return true;
}
#Override
public int getCount() {
return ((null != categoryList) ?
categoryList.size() : 0);
}
#Override
public Category getItem(int position) {
return ((null != categoryList) ?
categoryList.get(position) : null);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (null == view) {
view = layoutInflater.inflate(R.layout.grid_category, null);
}
final Category category = categoryList.get(position);
Log.d("categorygridlist",category.getName()+" "+position+ " " + categoryList.size());
if (category != null) {
final CardView categoryGridLayout = (CardView) view.findViewById(R.id.category_gridlayout);
final TextView categoryName = (TextView) view.findViewById(R.id.category_name);
final ImageView categoryIcon = (ImageView) view.findViewById(R.id.category_icon);
categoryName.setText(category.getName());
categoryName.setSelected(true);
try {
byte[] decodedString = Base64.decode(category.getImage(), Base64.DEFAULT);
BitmapFactory.Options options=new BitmapFactory.Options();// Create object of bitmapfactory's option method for further option use
options.inPurgeable = true; // inPurgeable is used to free up memory while required
Bitmap decodedByte1 = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);//Decode image, "thumbnail" is the object of image file
Bitmap decodedByte = Bitmap.createScaledBitmap(decodedByte1, 50 , 50 , true);// convert decoded bitmap into well scalled Bitmap format.
categoryIcon.setImageBitmap(decodedByte);
} catch (Exception e) {
e.printStackTrace();
}
categoryGridLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "worked", Toast.LENGTH_LONG).show();
}
});
}
return view;
}
I expect it will display item category at view pager when user select item tab and job category at view pager when user select job tab but it only display the job category. Anyone got solutions about this? Thanks
In the ViewPagerAdapter class, you have a List<Category> categoryList that you're passing to both Fragments in their constructors, and each Fragment is setting that same list as its dataset. The log prints you have in the setCategory() and update() methods only seem correct, because the updates are happening sequentially, and you're clearing the list in between.
Instead of passing that List to each Fragment, just have each one create its own new ArrayList<Category>, and remove that parameter from each constructor.
I am facing a problem, I could not remove an Item in RecyclerView.
I am trying to search in Internet, but could not see any solution
I am following to this post
Android RecyclerView addition & removal of items
But I still could not remove the item selected
Below is my code for my adapter and fragement
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
List<VideoDetails> contents2;
Context mContext;
ImageLoader imageLoader;
static final int TYPE_HEADER = 0;
static final int TYPE_CELL = 1;
public RecyclerViewAdapter(List<VideoDetails> contents) {
this.contents2 = contents;
}
public RecyclerViewAdapter(Context context, List<VideoDetails> contents) {
mContext = context;
this.contents2 = contents;
imageLoader = new ImageLoader(context);
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getItemCount() {
return contents2.size();
}
#Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
View view = null;
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_card_small2, parent, false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder,final int position) {
holder.title.setText(contents2.get(position).getTitle());
holder.image.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
Log.d("thien.van","on Click onBindViewHolder");
contents2.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, contents2.size());
}
});
}
public Bitmap getThumbnail(String str) {
Bitmap bMap = ThumbnailUtils.createVideoThumbnail(str, MediaStore.Video.Thumbnails.MINI_KIND);
return bMap;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView title;
public ImageView image;
public ProgressBar progressBar;
public ViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
image = (ImageView) itemView.findViewById(R.id.thumbnail);
progressBar = (ProgressBar) itemView.findViewById(R.id.progress);
// image.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Log.d("thien.van","onClick getAdapterPosition () = "+getAdapterPosition());
removeAt(getAdapterPosition());
}
}
public void removeAt(int position) {
contents2.remove(position);
notifyDataSetChanged();
}
}
RecyclerViewFragment
public class RecyclerViewFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private static final int ITEM_COUNT = 2;
private List<Object> mContentItems = new ArrayList<>();
private static List<VideoDetails> mContentItems2 = new ArrayList<>();
public static RecyclerViewFragment newInstance() {
return new RecyclerViewFragment();
}
public static RecyclerViewFragment newInstance(List<VideoDetails> contentItems) {
RecyclerViewFragment myFragment = new RecyclerViewFragment();
// mContentItems = contentItems;
Bundle args = new Bundle();
args.putSerializable("thienvan", (Serializable) contentItems);
myFragment.setArguments(args);
return myFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mContentItems2 = (List<VideoDetails>) getArguments().getSerializable("thienvan");
// Log.d("thien.van","Fragment file name = "+mContentItems2.get(0).getTitle());
return inflater.inflate(R.layout.fragment_recyclerview, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(layoutManager);
//mRecyclerView.setHasFixedSize(true);
mAdapter = new RecyclerViewMaterialAdapter(new RecyclerViewAdapter(getActivity().getBaseContext(),mContentItems2));
mRecyclerView.setAdapter(mAdapter);
/*{
for (int i = 0; i < ITEM_COUNT; ++i)
mContentItems.add(new Object());
mAdapter.notifyDataSetChanged();
}*/
MaterialViewPagerHelper.registerRecyclerView(getActivity(), mRecyclerView, null);
}
//http://android--code.blogspot.com/2015/12/android-recyclerview-add-remove-item.html
}
I could not remove an item inside Adapter class.
Anybody could help me ?
To get the correct position for remove you should call holder.getAdapterPosition() and use this value for all remove and notify operations. Android studio shows a warning for this, so make sure to check the warnings first. And why for getItemCount you return 2?
public void onClick(View view) {
int newPosition = holder.getAdapterPosition();
Log.d("thien.van","on Click onBindViewHolder");
contents2.remove(newPosition);
notifyItemRemoved(newPosition);
notifyItemRangeChanged(newPosition, contents2.size());
}
Remove single item
Remove "Pig" from the list.
int removeIndex = 2;
data.remove(removeIndex);
adapter.notifyItemRemoved(removeIndex);
Remove multiple items
Remove "Camel" and "Sheep" from the list.
int startIndex = 2; // inclusive
int endIndex = 4; // exclusive
int count = endIndex - startIndex; // 2 items will be removed
data.subList(startIndex, endIndex).clear();
adapter.notifyItemRangeRemoved(startIndex, count);
Remove all items
Clear the whole list.
data.clear();
adapter.notifyDataSetChanged();
I have a MainActivity which first makes a call to my server and gets the response. Then, on the success of first response, i am initiating the viewPager.
Below, code is called to initiate the viewPager and it's adapter, it is called only after the success of first response.
mShowTimeViewPageAdapter = new ShowTimeViewPageAdapter(getSupportFragmentManager(), getApplicationContext(), this, mDateStringList, showDateCodesList, venueHashMap);
mVenueHashMap = venueHashMap;
mRequestedDateCodes = requestedDateCodes;
mViewPager.setAdapter(mShowTimeViewPageAdapter);
mShowTimeTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < range; i++) {
TabLayout.Tab tab = mShowTimeTabLayout.getTabAt(i);
tab.setCustomView(mShowTimeViewPageAdapter.getTabView(i));
}
This is my viewPagerAdapter.
public class ShowTimeViewPageAdapter extends FragmentStatePagerAdapter {
private static final String TAG = ShowTimeViewPageAdapter.class.getSimpleName();
private Map<Integer, String> mFragmentTags;
private Context mContext;
private List<String> mDateStringList;
private FragmentManager fragmentManager;
private IShowTimeActivity mIShowTimeActivity;
private List<String> mDateCodes;
private LinkedHashMap<String, List<Venue>> mVenueHashMap;
public ShowTimeViewPageAdapter(FragmentManager fm, Context context, IShowTimeActivity showTimeActivity, List<String> createdDates, List<String> dateCodes, LinkedHashMap<String, List<Venue>> venueHashMap) {
super(fm);
this.mContext = context;
this.mIShowTimeActivity = showTimeActivity;
this.fragmentManager = fm;
this.mDateCodes = dateCodes;
this.mVenueHashMap = venueHashMap;
this.mDateStringList = createdDates;
mFragmentTags = new HashMap<Integer, String>();
}
private List<Venue> getVenuesList(String dateCode) {
return mVenueHashMap.get(dateCode);
}
#Override
public Fragment getItem(int position) {
String stringDate = mDateStringList.get(position).split(";")[2];
if (mDateCodes.contains(stringDate)) {
if (getVenuesList(stringDate) == null) {
mIShowTimeActivity.requestForTheVenueListByDateCode(stringDate, position);
}
}
ShowTimeFragment showTimeFragment = ShowTimeFragment.newInstance(stringDate);
showTimeFragment.setVenueList(mVenueHashMap.get(stringDate));
// fragmentManager.beginTransaction().add(showTimeFragment, ""+position);
return showTimeFragment;
}
#Override
public int getCount() {
return mDateStringList.size();
}
public View getTabView(int position) {
String[] dateStr = mDateStringList.get(position).split(";");
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View tabView = layoutInflater.inflate(R.layout.show_time_tab_layout, null, false);
TextViewRoboto day = (TextViewRoboto) tabView.findViewById(R.id.show_time_tab_day);
TextViewRoboto date = (TextViewRoboto) tabView.findViewById(R.id.show_time_tab_date);
day.setText(dateStr[0]);
date.setText(dateStr[1]);
return tabView;
}
}
Here, on getItem() method callback of viewPager, it creates a new fragment for each position and checks if the data for the selected position is available or not. If yes, which will be obviously there for the first position, since it was called after success of first response, it will pass the data to the fragment.
If not, it will make a new api request to the server, to get the data.
Since viewPager caches 2 pages, in advance, it will make 2 requests and cache the data.
In each request, i am updating the hashMap with data.
This is my fragment, which is always initiated for each position.
public class ShowTimeFragment extends Fragment {
private static final String KEY_CODE = "date_key";
public ShowTimeRecyclerViewAdapter mShowTimeRecyclerViewAdapter;
#Bind(R.id.show_time_fragment_recycler_view) RecyclerView mShowTimeRecyclerView;
#Bind(R.id.show_time_fragment_no_data_text_view) TextViewRoboto mShowTimeNoDataTextView;
List<Venue> venueList = new ArrayList<Venue>();
public List<Venue> getVenueList() {
return venueList;
}
public void setVenueList(List<Venue> venueList) {
this.venueList = venueList;
}
private View view;
public ShowTimeFragment() {
}
public static ShowTimeFragment newInstance(String dateCode) {
Bundle bundle = new Bundle();
bundle.putString(KEY_CODE, dateCode);
ShowTimeFragment showTimeFragment = new ShowTimeFragment();
showTimeFragment.setArguments(bundle);
return showTimeFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.show_time_fragment, container, false);
ButterKnife.bind(this, view);
mShowTimeRecyclerViewAdapter = new ShowTimeRecyclerViewAdapter(venueList, getContext());
mShowTimeRecyclerView.setAdapter(mShowTimeRecyclerViewAdapter);
if (venueList != null && venueList.size() > 0) {
mShowTimeRecyclerView.setVisibility(View.VISIBLE);
mShowTimeNoDataTextView.setVisibility(View.GONE);
CustomLinearLayoutManager cl = new CustomLinearLayoutManager(getActivity(), 1, false);
mShowTimeRecyclerView.setLayoutManager(cl);
}
else{
mShowTimeNoDataTextView.setVisibility(View.VISIBLE);
mShowTimeRecyclerView.setVisibility(View.GONE);
mShowTimeNoDataTextView.setText("NO Data Available");
}
return view;
}
}
And Below is my recyclerViewAdapter, which is called from the fragment.
public class ShowTimeRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_RECOMMENDED = 0;
private static final int TYPE_GENERIC = 1;
public List<Venue> mVenueList;
private Context mContext;
public ShowTimeRecyclerViewAdapter(List<Venue> venueList, Context context) {
this.mVenueList = venueList;
this.mContext = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_RECOMMENDED) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.show_time_recycler_view_header_item_view, parent, false);
final RecommendedViewHolder recyclerViewHolder = new RecommendedViewHolder(view);
return recyclerViewHolder;
}
else if (viewType == TYPE_GENERIC) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.show_time_recycler_view_item, parent, false);
final ChildViewHolder viewHolder = new ChildViewHolder(view);
return viewHolder;
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Venue venue = mVenueList.get(position);
if (holder instanceof RecommendedViewHolder) {
TextViewRoboto cinemaHallName = ((RecommendedViewHolder) holder).mRecommendedShowTimeCinemaHallName;
cinemaHallName.setText(venue.getVenueName());
CustomGridView movieTimingGridView = ((RecommendedViewHolder) holder).mRecommendedMovieTimingGridView;
ImageView reserveIcon = ((RecommendedViewHolder) holder).mRecommendedMovieReserveImage;
if (venue.getCinemaUnpaidFlag().equals("Y")) {
reserveIcon.setVisibility(View.VISIBLE);
}
else {
reserveIcon.setVisibility(View.GONE);
}
ImageView mTicketIcon = ((RecommendedViewHolder) holder).mRecommendedMovieMTicketImage;
if (venue.getMTicket().equals("Y")) {
mTicketIcon.setVisibility(View.VISIBLE);
}
else {
mTicketIcon.setVisibility(View.GONE);
}
List<ShowTime> currShowTimesList = new ArrayList<ShowTime>(venue.getShowTimes());
movieTimingGridView.setAdapter(new ShowMovieTimeAdapter(mContext, currShowTimesList, true));
movieTimingGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
else if (holder instanceof ChildViewHolder) {
((ChildViewHolder) holder).mShowTimeCinemaHallName.setText(venue.getVenueName());
if (venue.getMTicket().toUpperCase().equals("Y") || venue.getCinemaUnpaidFlag().toUpperCase().equals("Y")) {
if (venue.getCinemaUnpaidFlag().toUpperCase().equals("N")) {
((ChildViewHolder) holder).mMovieReserveImage.setVisibility(View.GONE);
}
else if (venue.getCinemaUnpaidFlag().toUpperCase().equals("Y")) {
((ChildViewHolder) holder).mMovieReserveImage.setVisibility(View.VISIBLE);
((ChildViewHolder) holder).mMovieReserveImage.setImageResource(R.drawable.show_time_reserve_seat_icon);
}
if (venue.getMTicket().toUpperCase().equals("N")) {
((ChildViewHolder) holder).mMovieMTicketImage.setVisibility(View.GONE);
}
else if (venue.getMTicket().toUpperCase().equals("Y")) {
((ChildViewHolder) holder).mMovieMTicketImage.setVisibility(View.VISIBLE);
((ChildViewHolder) holder).mMovieMTicketImage.setImageResource(R.drawable.show_time_m_ticket_icon);
}
}
else {
((ChildViewHolder) holder).mShowTimeFragImagesLinearLayout.setVisibility(View.GONE);
}
CustomGridView movieTimingGridView = ((ChildViewHolder) holder).mMovieTimingGridView;
List<ShowTime> currShowTimesList = new ArrayList<ShowTime>(venue.getShowTimes());
movieTimingGridView.setAdapter(new ShowMovieTimeAdapter(mContext, currShowTimesList, false));
movieTimingGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
}
public static class ChildViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.show_time_fragment_cinema_hall_name)
TextViewRoboto mShowTimeCinemaHallName;
#Bind(R.id.show_movie_timings_grid_view)
CustomGridView mMovieTimingGridView;
#Bind(R.id.show_time_fragment_reserve_image)
ImageView mMovieReserveImage;
#Bind(R.id.show_time_fragment_m_ticket_image)
ImageView mMovieMTicketImage;
#Bind(R.id.show_time_fragment_images_lin_layout)
LinearLayout mShowTimeFragImagesLinearLayout;
public ChildViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
public void swap(List<Venue> venueList){
if(mVenueList!=null){
mVenueList.clear();
mVenueList.addAll(venueList);
} else {
mVenueList = venueList;
}
}
class RecommendedViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.show_time_recommendation_fragment_cinema_hall_name)
TextViewRoboto mRecommendedShowTimeCinemaHallName;
#Bind(R.id.show_movie_recommendation_timings_grid_view)
CustomGridView mRecommendedMovieTimingGridView;
#Bind(R.id.show_time_recommendation_fragment_reserve_image)
ImageView mRecommendedMovieReserveImage;
#Bind(R.id.show_time_recommendation_fragment_m_ticket_image)
ImageView mRecommendedMovieMTicketImage;
#Bind(R.id.show_time_recommendation_for_badge)
ImageView mShowTimeRecommendationBadge;
public RecommendedViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
#Override
public int getItemCount() {
return mVenueList.size();
}
#Override
public int getItemViewType(int position) {
if (isPositionRecommended(position))
return TYPE_RECOMMENDED;
return TYPE_GENERIC;
}
private boolean isPositionRecommended(int position) {
Venue venue = mVenueList.get(position);
return venue.isRecommended();
}
}
My problems lies here, even though the request is asynchronous, i want to show a loader, if the data hasn't come and the update the viewPager fragment on the data has come from server and hideLoading.
It's working fine when i am overriding getItemPosition() of viewPager and returning POSITION_NONE from there, but i don't want to do this, because it's recreating the fragment, and making my app slow.
I tried setting the TAG for each fragment and onPositionSelected() callback of viewPager listener, i tried swapping the recyclerView content for each fragment, but it didn't work.
Surprisingly, it loads all the data, if keep sliding to other pages and come back to 1st or 2nd page.
I tried all possible solution from my side.
Any kind suggestions would be appreciated.
This is how you keep your results, where you keep this is irrelevant
private LinkedHashMap<String, List<Venue>> mVenueHashMap;
And this is how you instantiate your fragment
ShowTimeFragment showTimeFragment = ShowTimeFragment.newInstance(stringDate);
You also want the fragment to load data if it is visible to user, if I am not mistaken, So you shall do the following in your fragment
public class ShowTimeFragment extends Fragment {
private String mStringDate; //obtained and stored here from pager adapter
private List<Venue> yourResults; // also obtained from pager adapter
#Override
public void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.show_time_fragment, container, false);
ButterKnife.bind(this, view);
//at this point the progress bar should be visible.. view initilaisations are
//omitted to keep the code simple
if(yourResults != null){
//hide progress, show data
}
return view;
}
#Override
public void setUserVisibilityHint(boolean isVisibleToUser){
super.setUserVisibilityHint(isVisibleToUser)
//assuming you keep track of requests made for each dates in your activity
if(isVisibleToUser && yourResults== null &&
!myActivity.isRequestingForDate(mStringDate)){
// tell your activity here to load the data for this particular date
// if there is no data and there is no ongoing request for current date
}
}
#Override
public void onResume(){
super.onResume();
EventBus.getInstance().register(this);
}
#Override
public void onPause(){
super.onPause();
EventBus.getInstance().unregister(this);
}
#Subscribe
public void onVenueReceived(VenueResponse response){
if(mStringdate.equals(response.getDate())){
yourResult = response.getVenues();
// hide progressbar and show data here
}
}
}
and your VenueResponse class would look like this
public final class VenueResponse {
String date;
List<Venue> venues;
public VenueResponse(String date, List<Venue> venues) {
this.date = date;
this.venues = venues;
}
public List<Venues> getVenues(){
return venues;
}
public String getDate(){
return date;
}
}
in your activity, wherever you are receiving the network response, you would do the following to save and notify fragments
String date; // requested date
List<Venue> venues; // received from network call for a particular date
mVenueHashMap.put(date, venues); // saves to the hashmap you maintain
// if a fragment with this particular date is currentlly visible to user, it will
// receive the following broadcast. if not, it will get the cached
// response in `onCreateView()` lifecycle method when it becomes visible again
EventBus.getInstance().post(new VenueResponse(date, venues));
It is quiet a work but serves the purpose :)