I've created a Fragment that should display some emojis in my GridView, when I try to put the URLs statically outside the public void call method the images get displayed successfully however when I put the code inside this method, the images don't display, I'm doing this for testing as I'm going to make it dynamic, but this is just for testing.
So, appreciate your assistance to advise why the images are not appearing inside this method specifically.
BottomSheetFragment.java
public class BottomSheetFragment extends BottomSheetDialogFragment {
ArrayList<EmojiModel> emojieModels = new ArrayList<>();;
ArrayList<String> imageId = new ArrayList<>();
View grid;
GridView gridView;
ImageAdapter2 imageAdapter2;
public BottomSheetFragment() {
// Empty Constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.gifts_layout_2, container,
false);
gridView = (GridView)rootView.findViewById(R.id.grid_view2);
getEmojies();
imageAdapter2 = new ImageAdapter2(getActivity().getApplicationContext(),
imageId);
gridView.setAdapter(imageAdapter2);
return rootView;
}
public void getEmojies(){
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Communicator.getInstance().on("subscribe start", new
Emitter.Listener() {
#Override
public void call(Object... args) {
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
}
});
}
});
}
public class ImageAdapter2 extends BaseAdapter {
private Context context;
private ArrayList<String> emojieImages = new ArrayList<>();
// Constructor
public ImageAdapter2(Context context, ArrayList<String> emojieImages) {
this.context = context;
this.emojieImages = emojieImages;
}
#Override
public int getCount() {
return emojieImages.size();
}
#Override
public Object getItem(int position) {
return emojieImages.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder {
ImageView imageView;
}
#Override
public View getView(final int position, View convertView, ViewGroup
parent) {
Holder holder = new Holder();
LayoutInflater inflater = (LayoutInflater)
getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
grid = inflater.inflate(R.layout.smiles_items_layout, null);
holder.imageView = (ImageView)
grid.findViewById(R.id.smile_image_view);
Picasso.with(getApplicationContext())
.load(emojieImages.get(position))
.fit()
.centerInside()
.into(holder.imageView);
notifyDataSetChanged();
return grid;
}
}
}
That's because your method runOnUIThread is asynchronous.
To make it work you should set the adapter after the images are loaded:
#Override
public void call(Object... args) {
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
imageId.add("https://static.pexels.com/photos/247932/pexels-photo-
247932.jpeg");
imageAdapter2 = new ImageAdapter2(getActivity(), imageId);
gridView.setAdapter(imageAdapter2);
}
Also note that you don't need to call runOnUIThread inside a Fragment, it is already running on that thread.
Maybe your image access problems
https://static.pexels.com/photos/247932/pexels-photo-%20247932.jpeg
Can not access
Related
I am a beginner at android development. I tried to display data on Recycle View using MVVM. When I opened the fragment the first time it is empty, the second time it showed data. Adapter not called the first time. How to fix this.
Fragment class
public class fragmentEmployee extends Fragment {
private FragmentEmployeeBinding binding;
private ViewGroup viewGroup;
private View view;
private RecyclerView mRecycleView;
private UserAdapter mAdapter;
private EmployeeRegisterViewModel viewModel;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_employee, viewGroup, false);
view = binding.getRoot();
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Toast.makeText(getContext(), "onViewCreated", Toast.LENGTH_SHORT).show();
mRecycleView = binding.recyleViewEmployee;
viewModel = new ViewModelProvider(this).get(EmployeeRegisterViewModel.class);
viewModel.init();
initRecycleView();
viewModel.getEmployee().observe(getViewLifecycleOwner(), new Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.notifyDataSetChanged();
}
});
}
private void initRecycleView() {
mAdapter = new UserAdapter(getContext(), viewModel.getEmployee().getValue());
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
mRecycleView.setLayoutManager(layoutManager);
mRecycleView.setAdapter(mAdapter);
}
}
UserAdapter class
public class UserAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
public List<employeeModel> employeeModelList= new ArrayList<>();
public Context context1;
public UserAdapter(Context context,List<employeeModel> employeeModels){
employeeModelList = employeeModels;
context1 = context;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_listitem,parent,false);
ViewHolder viewHolder=new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
(ViewHolder)holder).username.setText(employeeModelList.get(position).getName());
}
#Override
public int getItemCount() {
return employeeModelList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView username;
public ViewHolder(#NonNull View itemView) {
super(itemView);
username=itemView.findViewById(R.id.userText);
}
}
}
Try reordering like this.
Remove
mAdapter = new UserAdapter(getContext(), viewModel.getEmployee().getValue());
from initRecycleView
mAdapter = new UserAdapter(getContext(), viewModel.getEmployee().getValue());
viewModel.getEmployee().observe(getViewLifecycleOwner(), new Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.notifyDataSetChanged();
}
});
initRecycleView();
mAdapter.notifyDataSetChanged();
Above method will work if the list declared inside adapter has any change. So, calling above method without changing adapter's list is useless.
Add a method to UserAdapter class to update list data. Like:
public void updateData(List<employeeModel> updatedList){
employeeModelList.clear();
employeeModelList.addAll(updatedList);
notifyDataSetChanged();
}
And call this method inside observer. Like:
viewModel.getEmployee().observe(getViewLifecycleOwner(), new
Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.updateData(employeeModels);
}
});
where are you get your network data?
If your get in here -> viewModel.init();
I think it just timing problem.
Just change code sequence
initRecycleView();
viewModel.getEmployee().observe(getViewLifecycleOwner(), new Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.notifyDataSetChanged();
}
});
viewModel.init();
I am having problems updating my RecyclerView with new data. If I press a confirmation button on a CardView in the first tab, the card should get added to the second tab but it won't update it there until I rotate the screen. I get the data for the card from reading a text file. Please advise me how to call the notifyDataSetChange method after I have added the new data to my text file. I have tried everything and all I get is NullPointerExceptions. The RecyclerViews are in fragments and I use FragementStatePagerAdapter.
I'll put some of my classes here. Ask if you need more information.
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
private List<String> mListTitle;
private List<String> mListDesc;
private List<String> mListPoints;
private List<String> mListDates;
private String fragment_tag;
public RecyclerViewAdapter() {
}
public RecyclerViewAdapter(List<List<String>> super_list, String tag) {
this.mListTitle = super_list.get(0);
this.mListDesc = super_list.get(1);
this.mListPoints = super_list.get(2);
this.mListDates = super_list.get(3);
fragment_tag = tag;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new RecyclerViewHolder(inflater, parent, fragment_tag);
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.mTitleText.setText(mListTitle.get(position));
holder.mDescText.setText(mListDesc.get(position));
holder.mPointsText.setText(mListPoints.get(position));
if (fragment_tag.equals("completed")) {
holder.mDateText.setText(mListDates.get(position));
}
}
#Override
public int getItemCount() {
return mListTitle.size();
}
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
RecyclerView recyclerView;
RecyclerViewAdapter mAdapter;
public TextView mTitleText, mDescText, mDateText, mPointsText, popupTitle;
public Button mConfButton, popCancelBtn, popAcceptBtn;
public RecyclerViewHolder(View itemView) {
super(itemView);
}
public RecyclerViewHolder(final LayoutInflater inflater, final ViewGroup container, String tag) {
// Inflating the card layout depending on the tag parameter.
super(inflater.inflate
((tag.equals("challenges")) ? R.layout.card_view_chall : R.layout.card_view_comp, container,
false));
mTitleText = itemView.findViewById(R.id.title_holder);
mDescText = itemView.findViewById(R.id.desc_holder);
mPointsText = itemView.findViewById(R.id.points_holder);
mDateText = itemView.findViewById(R.id.date_holder);
if (tag.equals("challenges")) {
mConfButton = itemView.findViewById(R.id.card_conf_button);
mConfButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Setting the layout inflater for popup window.
LayoutInflater pInflater = (LayoutInflater) itemView.getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
ViewGroup container1 = (ViewGroup) pInflater.inflate(R.layout.confirmation_popup, null);
final PopupWindow popupWindow = new PopupWindow(container1, 700, 600, true);
popupTitle = container1.findViewById(R.id.popuptext);
popAcceptBtn = container1.findViewById(R.id.accept_button);
popCancelBtn = container1.findViewById(R.id.cancel_button);
popupTitle.setText(mTitleText.getText().toString());
// Dismisses the popup window
popCancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
popupWindow.dismiss();
}
});
// Click listener for dialog accept button.
popAcceptBtn.setOnClickListener(new View.OnClickListener() {
String date;
#Override
public void onClick(View view) {
List<String> list = new ArrayList<>();
list.add(mTitleText.getText().toString());
list.add(mDescText.getText().toString());
list.add(mPointsText.getText().toString());
list.add(date = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date()));
// Saving data from current card into the completed challenges list.
TempDataReader reader = new TempDataReader(itemView.getContext());
new TempDataReader(itemView.getContext()).saveFile(list);
// I want to notify the dataset change here if possible!
popupWindow.dismiss();
}
});
popupWindow.showAtLocation(itemView, Gravity.CENTER, 25, 100);
}
});
}
}
}
SectionsPagerAdapter.java
public class SectionsPagerAdapter extends FragmentStatePagerAdapter{
private ViewPager viewPager;
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
CompletedFragment.java
public class CompletedFragment extends Fragment {
RecyclerView recyclerView;
RecyclerViewAdapter adapter;
public Fragment newInstance() {
return new CompletedFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.completed_fragment, container, false);
recyclerView = view.findViewById(R.id.completed_frag);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
TempDataReader reader = new TempDataReader(getActivity());
List<List<String>> super_list = reader.readCompFile();
if(super_list == null || super_list.size() < 1){
return null;
} else{
adapter = new RecyclerViewAdapter(super_list,"completed");
recyclerView.setAdapter(adapter);
return view;
}
}
}
EDIT:
Added the code for the second fragment, which is the one that should be updated after the onClick at RecyclerViewHolder-class.
You have to add a function in your adapter for adding data:
public void addData(String title, String desc, String point, String date) {
this.mListTitle.add(title);
this.mListDesc.add(desc);
this.mListPoints.add(point);
this.mListDates.add(date);
notifyDataSetChanged();
}
If you want to enable animations call notifyItemInserted() instead of notifyDataSetChanged();
It is important that you add a String to every list because in your onBindViewHolder() you get the item to display from every list with list.get(position). Otherwise you'll get a IndexOutOfBoundsException.
You can create an interface and use as a callback. Send it as a parameter of the RecyclerViewAdapter and then to your RecyclerViewHolder. When the item should be added you call the callback that will get you back to your fragment. There you can read the file again and call notifyDataSetChanged.
I know i explain pretty bad so i will try to change your code so that it does what i said:
this will be your RecyclerViewAdapter:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
private List<String> mListTitle;
private List<String> mListDesc;
private List<String> mListPoints;
private List<String> mListDates;
private String fragment_tag;
private Runnable callback;
public RecyclerViewAdapter() {
}
public RecyclerViewAdapter(List<List<String>> super_list, String tag, Runnable callBack) {
//add the callback here(Runnable) and save it into a local variable
this.callback=callback;
this.mListTitle = super_list.get(0);
this.mListDesc = super_list.get(1);
this.mListPoints = super_list.get(2);
this.mListDates = super_list.get(3);
fragment_tag = tag;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new RecyclerViewHolder(inflater, parent, fragment_tag, callback);
//send the callback to your viewHolder
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.mTitleText.setText(mListTitle.get(position));
holder.mDescText.setText(mListDesc.get(position));
holder.mPointsText.setText(mListPoints.get(position));
if (fragment_tag.equals("completed")) {
holder.mDateText.setText(mListDates.get(position));
}
}
#Override
public int getItemCount() {
return mListTitle.size();
}
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
RecyclerView recyclerView;
RecyclerViewAdapter mAdapter;
public TextView mTitleText, mDescText, mDateText, mPointsText, popupTitle;
public Button mConfButton, popCancelBtn, popAcceptBtn;
public RecyclerViewHolder(View itemView) {
super(itemView);
}
public RecyclerViewHolder(final LayoutInflater inflater, final ViewGroup container, String tag, Runnable callback) {
//ADD the callback to the parameters list here
// Inflating the card layout depending on the tag parameter.
super(inflater.inflate
((tag.equals("challenges")) ? R.layout.card_view_chall : R.layout.card_view_comp, container,
false));
mTitleText = itemView.findViewById(R.id.title_holder);
mDescText = itemView.findViewById(R.id.desc_holder);
mPointsText = itemView.findViewById(R.id.points_holder);
mDateText = itemView.findViewById(R.id.date_holder);
if (tag.equals("challenges")) {
mConfButton = itemView.findViewById(R.id.card_conf_button);
mConfButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Setting the layout inflater for popup window.
LayoutInflater pInflater = (LayoutInflater) itemView.getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
ViewGroup container1 = (ViewGroup) pInflater.inflate(R.layout.confirmation_popup, null);
final PopupWindow popupWindow = new PopupWindow(container1, 700, 600, true);
popupTitle = container1.findViewById(R.id.popuptext);
popAcceptBtn = container1.findViewById(R.id.accept_button);
popCancelBtn = container1.findViewById(R.id.cancel_button);
popupTitle.setText(mTitleText.getText().toString());
// Dismisses the popup window
popCancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
popupWindow.dismiss();
}
});
// Click listener for dialog accept button.
popAcceptBtn.setOnClickListener(new View.OnClickListener() {
String date;
#Override
public void onClick(View view) {
List<String> list = new ArrayList<>();
list.add(mTitleText.getText().toString());
list.add(mDescText.getText().toString());
list.add(mPointsText.getText().toString());
list.add(date = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date()));
// Saving data from current card into the completed challenges list.
TempDataReader reader = new TempDataReader(itemView.getContext());
new TempDataReader(itemView.getContext()).saveFile(list);
// I want to notify the dataset change here if possible!
//call the callback
callback.run();
popupWindow.dismiss();
}
});
popupWindow.showAtLocation(itemView, Gravity.CENTER, 25, 100);
}
});
}
}
}
And this will be your fragment:
public class CompletedFragment extends Fragment {
RecyclerView recyclerView;
RecyclerViewAdapter adapter;
public Fragment newInstance() {
return new CompletedFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.completed_fragment, container, false);
recyclerView = view.findViewById(R.id.completed_frag);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
TempDataReader reader = new TempDataReader(getActivity());
List<List<String>> super_list = reader.readCompFile();
if(super_list == null || super_list.size() < 1){
return null;
} else{
adapter = new RecyclerViewAdapter(super_list,"completed", new Runnable() {
#Override
public void run() {
//here read the list again and call notifyDataSetChanged on your recycler
}
});
);
recyclerView.setAdapter(adapter);
return view;
}
}
}
Hope it helps and it works for you. If i did anything wrong, let me know, i can't run the code right now so...
edited, i forgot to add code in the callback
I try to load the database from firebase database and get this exception. It is about the notifyDataSetChanged. I has tried to put in in getCount() in SlideShowAapter but it has not worked.
Exceptions:
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged!
Expected adapter item count: 0, found: 1 Pager id: com.example.dave.lomoapp:id/slideShow Pager class: class android.support.v4.view.ViewPager
Problematic adapter: class com.example.davenguyen.lomoapp.SlideShowAdapter
at android.support.v4.view.ViewPager.populate(ViewPager.java:1135)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:662)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:624)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:616)
at com.example.davenguyen.lomoapp.HomeFragment$1.run(HomeFragment.java:71)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
This my SlideShowAdapter
public class SlideShowAdapter extends PagerAdapter {
private boolean doNotifyDataSetChangedOnce = false;
private ArrayList<Genre> genresList;
private LayoutInflater inflater;
private Context context;
public SlideShowAdapter(Context context, ArrayList<Genre> images) {
this.context = context;
this.genresList =images;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount()
{
if (doNotifyDataSetChangedOnce) {
doNotifyDataSetChangedOnce = false;
notifyDataSetChanged();
}
return genresList.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View myImageLayout = inflater.inflate(R.layout.slide, view, false);
ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.slideShowImg);
Picasso.with(context).load(genresList.get(position).getImage()).into(myImage);
view.addView(myImageLayout, 0);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return myImageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
}
This a fragment that has my custom adapter
public class HomeFragment extends Fragment {
private static ViewPager mPager;
private static int currentPage = 0;
private ArrayList<Genre> genreList = new ArrayList<Genre>();
DatabaseReference mref;
public HomeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v =inflater.inflate(R.layout.fragment_home, container, false);
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
loadImage();
mPager = (ViewPager) view.findViewById(R.id.slideShow);
mPager.setAdapter(new SlideShowAdapter(getActivity(), genreList));
CircleIndicator indicator = (CircleIndicator) view.findViewById(R.id.indicator);
indicator.setViewPager(mPager);
// Auto start of viewpager
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage == genreList.size()) {
currentPage = 0;
}
mPager.setCurrentItem(currentPage++, true);
}
};
Timer swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 2500, 2500);
}
private void loadImage() {
// Get a reference to our genres
mref = FirebaseDatabase.getInstance().getReference().child("genres");
// Attach a listener to read the data at our genres reference
mref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
genreList.add (dataSnapshot.getValue(Genre.class));
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.i("READ_FAIELD","The read failed: " + databaseError.getCode());
}
});
}
}
Thanks in advance
My guess is that the problem is that flag doNotifyDataSetChangedOnce in your adapter. Try to remove that if and call adapter.notifyDataSetChanged() after your image is loaded (in onDataChange).
If this solves the crash but the viewPager is not updated, you might need to add this code in your adapter:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Write this way :
SlideShowAdapter adapter=new SlideShowAdapter(getActivity(), genreList);
mPager.setAdapter(adapter);
adapter.notifyDataSetChanged();
Instead of
mPager.setAdapter(new SlideShowAdapter(getActivity(), genreList));
Try changing in instantiateItem with this:
View myImageLayout = inflater.inflate(R.layout.slide, view, false);
ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.slideShowImg);
Picasso.with(context).load(genresList.get(position).getImage()).into(myImage);
.
myImageLayout.addView(myImage, 0);
myImageLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return myImageLayout;
And remove :
if (doNotifyDataSetChangedOnce) {
doNotifyDataSetChangedOnce = false;
notifyDataSetChanged();
}
I need to get the vales passed from ThePagerAdapter.java inside SliderHome.java. How can I implement this? I have tried a lot, but no success.
This is my code:
ThePagerAdapter.java
public class ThePagerAdapter extends PagerAdapter {
Context context;
#Override
public int getCount() {
return list.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
public ThePagerAdapter(Context context,List<Slider> list) {
this.list = list;
this.context = context;
}
#Override
public Object instantiateItem(final ViewGroup container, int position) {
// Declare Variables
ImageView imgflag;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.image_item, container, false);
// Capture position and set to the TextViews
final String id = list.get(position).getId();
imgflag = (ImageView) itemView.findViewById(R.id.imageView);
imgflag.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent i = new Intent(context, SliderMore.class);
i.putExtra("slider_id", id);
context.startActivity(i);
}
});
((ViewPager) container).addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// Remove viewpager_item.xml from ViewPager
((ViewPager) container).removeView((RelativeLayout) object);
}
}
From the above PagerAdapter I am send values to another Fragment described below using Intent.putExtra
SliderHome.java
public class SliderHome extends Fragment {
ViewPager viewPager;
ImageView iv2,iv3;
String slider_id;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.slider_more, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.viewPager);
iv2 = (ImageView) rootView.findViewById(R.id.imageView2);
iv3 = (ImageView) rootView.findViewById(R.id.imageView3);
return rootView;
}
Is there a solution? Thanks in advance.
In this cases I like to use a Factory Method Pattern.
Example:
public static MatchDetailSummaryFragment newInstance(String matchIdString, int position) {
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putString(ARGS_MY_ID, matchIdString);
args.putInt(ARG_POSITION,position);
fragment.setArguments(args);
return fragment;
}
public MyFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mPosition = getArguments().getInt(ARG_POSITION);
this.id = getArguments().getString(ARGS_MY_ID) != null)
}
You can invoke this:
public void fillMyPagerAdapter()
{
mChildFragments = new Hashtable<Integer,GxuBaseFragment>();
int count = 0;
MyFragment a = MyFragment.newInstance(Integer.toString(my.getId()),count);
mChildFragments.put(count,a);
count += 1;
mViewPagerAdapter.setTabHolderScrollingContent(this);
mPager.setAdapter(mViewPagerAdapter);
mPagerSlidingTabStrip.setViewPager(mPager);
mPagerSlidingTabStrip.setOnPageChangeListener(this);
}
This code may not work because is a couple of extracts of my production code but it will explain the main ideas.
I am using Base Adapter for displaying image in grid view. The working fine when images are fixed IMAGE_URLS directly but am try with geting url from list and assign into IMAGE_URLS that shows non static variable cannot be referenced from a static context. I don't know how to solve this issue. please help to solve this issue
public class ImageGridFragment extends AbsListViewBaseFragment {
public static final int INDEX = 1;
String description="";
ArrayList<String> img = new ArrayList<String>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fr_image_grid, container, false);
listView = (GridView) rootView.findViewById(R.id.grid);
img.clear();
Bundle bundle = this.getArguments();
description = bundle.getString("description");
String[] separated= description.split(",");
for(int i=0;i<separated.length;i++)
{
img.add(separated[i]);
}
ImageGalleryFragment.imageLoader.init(ImageLoaderConfiguration.createDefault(getActivity()));
((GridView) listView).setAdapter(new ImageAdapter(getActivity()));
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
startImagePagerActivity(position);
}
});
return rootView;
}
private static class ImageAdapter extends BaseAdapter {
String[] IMAGE_URLS = img.toArray(new String[img.size()]);
private LayoutInflater inflater;
private DisplayImageOptions options;
ImageAdapter(Context context) {
inflater = LayoutInflater.from(context);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
}
#Override
public int getCount() {
return IMAGE_URLS.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.item_grid_image, parent, false);
holder = new ViewHolder();
assert view != null;
holder.imageView = (ImageView) view.findViewById(R.id.image);
holder.progressBar = (ProgressBar) view.findViewById(R.id.progress);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
ImageLoader.getInstance()
.displayImage(IMAGE_URLS[position], holder.imageView, options, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
holder.progressBar.setProgress(0);
holder.progressBar.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
holder.progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
holder.progressBar.setVisibility(View.GONE);
}
}, new ImageLoadingProgressListener() {
#Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
holder.progressBar.setProgress(Math.round(100.0f * current / total));
}
});
return view;
}
}
static class ViewHolder {
ImageView imageView;
ProgressBar progressBar;
}
}
Change the class from private static to "private class ImageAdapter".