Only the first fragment is populated with the image, the second fragment is blank. I am using the same adapter for both fragments. I am not sure where is the problem.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mSectionsPagerAdapter.addFragment(PopularMoviesFragment.newInstance(SORT_POPULAR), "MOST POPULAR");
mSectionsPagerAdapter.addFragment(RatingMoviesFragment.newInstance(SORT_RATING), "TOP RATING");
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
public void switchToDetail(Intent intent){
startActivity(intent);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
static class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
}
First fragment
public static PopularMoviesFragment newInstance(String sort) {
PopularMoviesFragment fragment = new PopularMoviesFragment();
Bundle args = new Bundle();
args.putString("sort", sort);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sortOrder = getArguments().getString("sort");
mContext = getActivity();
if (savedInstanceState != null) {
mPopularList = savedInstanceState.getParcelableArrayList(POPULAR_LIST);
for (Movie m : mPopularList) {
Log.d(LOG_TAG, "onCreate: " + m.getTitle());
}
} else {
FetchPopularMovies pm = new FetchPopularMovies();
pm.execute(SORT_POPULAR);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View pView = inflater.inflate(R.layout.fragment_popular_movies, container, false);
mAdapter = new MoviePosterAdapter(mContext, mPopularList);
mProgressBar = (ProgressBar) pView.findViewById(R.id.movies_progress_bar);
RecyclerView mRecyclerView = (RecyclerView) pView.findViewById(R.id.my_recycler_view);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 3, GridLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
return pView;
}
Second fragment
public static RatingMoviesFragment newInstance(String sort) {
RatingMoviesFragment fragment = new RatingMoviesFragment();
Bundle args = new Bundle();
args.putString("sort", sort);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sortOrder = getArguments().getString("sort");
mContext = getActivity();
if (savedInstanceState != null) {
Log.d(LOG_TAG, "Has saved instance");
mRatingList = savedInstanceState.getParcelableArrayList(RATING_LIST);
} else {
FetchRatingMovies rm = new FetchRatingMovies();
rm.execute(SORT_RATING);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_rating_movies, container, false);
ratingAdapter = new MoviePosterAdapter(mContext, mRatingList);
mProgressBar = (ProgressBar) view.findViewById(R.id.movies_progress_bar);
RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 3, GridLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(ratingAdapter);
return view;
}
MoviePosterAdapter
public class MoviePosterAdapter extends RecyclerView.Adapter<MoviePosterAdapter.ViewHolder> {
private final String LOG_TAG = MoviePosterAdapter.class.getSimpleName();
final Context mContext;
private ArrayList<Movie> mDataset;
public static class ViewHolder extends RecyclerView.ViewHolder {
//public final View mView;
public final ImageView mImageView;
public ViewHolder(View view) {
super(view);
mImageView = (ImageView) view.findViewById(R.id.imageView);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MoviePosterAdapter(Context context, ArrayList<Movie> myDataset) {
this.mContext = context;
mDataset = myDataset;
}
public void setMoviesData(ArrayList<Movie> moviesData){
mDataset = moviesData;
}
// Create new views (invoked by the layout manager)
#Override
public MoviePosterAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(mContext).inflate(R.layout.movie_poster, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final Movie mMovie = mDataset.get(position);
//Creating URL for image
final String POSTER_BASE_URL = "http://image.tmdb.org/t/p/";
final String SIZE_PATH = "w185";
String IMG_PATH = mMovie.getImg();
//Loading image using Glide
Glide.with(holder.mImageView.getContext())
.load(POSTER_BASE_URL + SIZE_PATH + IMG_PATH)
.placeholder(R.color.grid_placeholder_bg)
.into(holder.mImageView);
holder.mImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mContext, DetailActivity.class);
i.putExtra("id", mMovie.getId());
i.putExtra("title", mMovie.getTitle());
if (mContext instanceof MainActivity) {
MainActivity main= (MainActivity) mContext;
main.switchToDetail(i);
}
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
Please help me!
EDIT: Both the arrays are not empty. Here is the issue I think, only one fragment gets populated, maybe because there is some problem with the adapter(not sure). If I try to stop first fragment to get populated(commenting out the notifyDatasetChanged()), then the second fragment works fine.
The image wasn't populating in the second fragment because it was an issue with Glide library. Switched to Picasso. Works fine.
I checked your code and i found that everything is fine. I tried with dummy data so i am damn sure that the mistake is in your data or adapter where you are setting data. Just try once with dummy data so you will be more clear or if still you are getting blank screen then let me know.
Generally blank screen comes because of there is no data. so please check once..
Related
I am building an Android Application which have Tab Layout in which there are Fragments and in Fragment I am displaying some value.
I have just only added hardcoded values to test the layout, but even these are not visible in the fragment.
Here is the code for ViewPagerAdapter:
public class FavouriteViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> favouriteFragmentList = new ArrayList<>(); // this line can cause crashes
private final List<String> favouriteFragmentListTitles = new ArrayList<>();
public FavouriteViewPagerAdapter(#NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
#NonNull
#Override
public Fragment getItem(int position) {
return favouriteFragmentList.get(position);
}
#Override
public int getCount() {
return favouriteFragmentListTitles.size();
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return favouriteFragmentListTitles.get(position);
}
public void AddFragment(Fragment fragment, String title) {
favouriteFragmentList.add(fragment); // this line can cause crashes
favouriteFragmentListTitles.add(title);
}
}
I have tried the answers available already none of them solves my problem.
I debugged the application and my RecyclerViewAdapter is not even called, very strange. I have done this many time but this never happened.
Here is my code for RecyclerViewAdapter :
public class ProductsRecyclerAdapter extends RecyclerView.Adapter<ProductsRecyclerAdapter.viewHolder> {
Context context;
private List<FavouriteProducts> favouriteProductsData;
public ProductsRecyclerAdapter(Context context, List<FavouriteProducts> favouriteProductsData) {
this.context = context;
this.favouriteProductsData = favouriteProductsData;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.single_favourite_product_item, parent, false);
viewHolder vHolder = new viewHolder(v);
return vHolder;
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
holder.product_name.setText(favouriteProductsData.get(position).getProduct_name());
holder.product_price.setText(favouriteProductsData.get(position).getProduct_price());
holder.product_image.setImageResource(favouriteProductsData.get(position).getProduct_image());
Toast.makeText(context,favouriteProductsData.get(position).getProduct_price() , Toast.LENGTH_SHORT).show();
/*holder.heart_button.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
showSuccessToast(context,"Liked");
}
#Override
public void unLiked(LikeButton likeButton) {
showSuccessToast(context,"Unliked");
}
});*/
}
#Override
public int getItemCount() {
return favouriteProductsData.size();
}
static class viewHolder extends RecyclerView.ViewHolder {
MaterialTextView product_name, product_price;
ImageView product_image;
LikeButton heart_button;
public viewHolder(#NonNull View itemView) {
super(itemView);
product_name = itemView.findViewById(R.id.product_name);
product_price = itemView.findViewById(R.id.product_price);
product_image = itemView.findViewById(R.id.product_image);
heart_button = itemView.findViewById(R.id.heart_button);
}
}
}
I am not getting any errors but after I check adapter is not even called. Some help will be really helpful.
Fragment Code:
public class FavouriteProductsFragment extends Fragment {
View v;
private List<FavouriteProducts> productList;
public FavouriteProductsFragment() {
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
productList = new ArrayList<>();
productList.add(new FavouriteProducts("All Weather", "200/Ltr", R.drawable.all_weather));
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.products_favourite_fragment, container, false);
RecyclerView productRecyclerView = v.findViewById(R.id.favourite_products_rv);
ProductsRecyclerAdapter recyclerAdapter = new ProductsRecyclerAdapter(getContext(), productList);
productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
productRecyclerView.hasFixedSize();
productRecyclerView.setAdapter(recyclerAdapter);
return v;
}
}
productList = new ArrayList<>();
productList.add(new FavouriteProducts("All Weather", "200/Ltr",R.drawable.all_weather));
recyclerAdapter.notifyDataSetChanged()
RecyclerView productRecyclerView = v.findViewById(R.id.favourite_products_rv);
ProductsRecyclerAdapter recyclerAdapter = new ProductsRecyclerAdapter(getContext(), productList);
productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
productRecyclerView.hasFixedSize();
productRecyclerView.setAdapter(recyclerAdapter);
You need to add
RecyclerView productRecyclerView = v.findViewById(R.id.favourite_products_rv);
ProductsRecyclerAdapter recyclerAdapter = new ProductsRecyclerAdapter(getContext(), productList);
productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
productRecyclerView.hasFixedSize();
productRecyclerView.setAdapter(recyclerAdapter);
productList = new ArrayList<>();
productList.add(new FavouriteProducts("All Weather", "200/Ltr",R.drawable.all_weather));recyclerAdapter.notifyDataSetChanged()
and Remove oncreate() method
try productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); befor setting adapter in recyclerview.
Step1: First Create one or MoreFragment For Your ViewPager and in This Fragment Add your Recyclerview Code as per Your Requirement.
Like Below Code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_whatsapp_image, container, false);
context = getActivity();
((HomeActivity) getActivity()).toolbar.setVisibility(View.VISIBLE);
setupView(root);
return root;
}
private void setupView(ViewGroup root) {
recyclerView = (RecyclerView) root.findViewById(R.id.recyclerViewImage);
progressBar=root.findViewById(R.id.simpleProgressBar);
txtinfo=root.findViewById(R.id.txtinfo);
setUPList();
}
Step2: Then Create ViewPager Adapter for Your TabLayout
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
if(position == 0) return new AudioFragment();
if(position == 1) return new VideoFragment();
if(position == 2) return new ImageFragment();
throw new IllegalStateException("Unexpected position " + position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
if(position == 0) return "Audio";
if(position == 1) return "Video";
if(position == 2) return "Image";
throw new IllegalStateException("Unexpected position " + position);
}
}
Step3 : Then Call Your SetupViewpager Method in Your Oncreate method of your Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=findViewById(R.id.toolbar);
viewPager=findViewById(R.id.viewpager);
tabLayout=findViewById(R.id.tabs);
//add toolbar
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
setTabIcons();
}
NOTE: You Can Download ViewPager Code from Below Link.Click Here to View and Download
My app has a fragment that host a nested viewPager (One fragment added every time) all views are linked to the same layout.
Each fragment has a fixed button + recylerview that retrieve its data from firebase adapter.
When I click on the button, it show the correct viewPager position. But if I click on the listview item (viewHolder) it show the next pre-loaded position in the viewPager.
here's the viewpager and the pager adapter of the root fragment
Explore.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_explore, container, false);
array = controller.SELECTED_CATEGORIES;
viewPager = (ViewPager) root.findViewById(R.id.viewPager);
tabLayout = (TabLayout) root.findViewById(R.id.categories_tablayout);
tabLayout.setupWithViewPager(viewPager);
mAdapter = new MyAdapter(getFragmentManager());
viewPager.setAdapter(mAdapter);
return root;
}
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return controller.SELECTED_CATEGORIES.length;
}
#Override
public Fragment getItem(int position) {
return CategoriesFragment.newInstance(position);
}
#Override
public CharSequence getPageTitle(final int position) {
return controller.SELECTED_CATEGORIES[position];
}
}
CategoriesFragment.java
static CategoriesFragment newInstance(int num) {
CategoriesFragment f = new CategoriesFragment();
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_categories, container, false);
initialize();
listCategoriesFeed = (RecyclerView) rootView.findViewById(R.id.listCategoriesFeeds);
categoriesFeedAdapter = new CategoriesFeedAdapter(CategoriesFeedItem.class, R.layout.categoriesfeed_list_item, CategoriesFeedHolder.class, myref);
llm = new LinearLayoutManager(rootView.getContext());
llm.setOrientation(LinearLayoutManager.VERTICAL);
listCategoriesFeed.setLayoutManager(llm);
listCategoriesFeed.setAdapter(categoriesFeedAdapter);
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
//Holder itemClickListener
CategoriesFeedHolder.registerOnItemClickListener(this);
//TextView onclick listener
View tv = rootView.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("position",mNum + "");
}
});
return rootView;
}
#Override
public void onItemClick(View view, int position) {
super.onItemClick(view, position);
switch (view.getId()) {
case R.id.firstId:
Log.e("position",mNum+ "");
break;
case R.id.secondId:
secondAction....
.....
.....
.....
break;
}
}
private void initialize() {
controller.showProgressDialog();
list = controller.getIniCategoriesDetailsList();
list.clear();
controller.categoriesDetailsList.put(controller.SELECTED_CATEGORIES[mNum],list);
reference = FirebaseDatabase.getInstance().getReference("firebase-path/" + controller.SELECTED_CATEGORIES[mNum]);
myref = reference.orderByChild("order-by").limitToFirst(i);
myref.addChildEventListener(this);
}
CategoriesFeedHolder.java
private CategoriesFeedItem model;
private final ImageView mImage;
private static OnItemClickListener onItemClickListener;
public CategoriesFeedHolder(View itemView) {
super(itemView);
this.context = itemView.getContext();
mImage = (ImageView) itemView.findViewById(R.id.m_image);
mImage.setOnClickListener(this);
}
public static void registerOnItemClickListener(OnItemClickListener onItemClickListener) {
CategoriesFeedHolder.onItemClickListener = onItemClickListener;
}
public void setModel(CategoriesFeedItem model) {
this.model = model;
}
#Override
public void onClick(View view) {
onItemClickListener.onItemClick(view, getAdapterPosition());
}
Does anyone know why this happens?
The problem was with the viewholder class, there was no data binding inside it. So when i clicked on any item inside the viewholder, it performed the action on the current adapter's data (preloaded data).
the viewholder class should be something like this:
public ViewHolder(View itemView) {
super(itemView);
share = (ImageView) itemView.findViewById(R.id.share);
}
public void bindToPost(Post post, View.OnClickListener onClickListener) {
share.setOnClickListener(onClickListener);
}
I'm building a simple stock display app that allows you to fetch stocks of interest (frag A), store them in a TinyDB, and display them in a recyclerView (frag B).
The framework used to work fine - until I decided to incorporate a viewpager and Tablayout host. I cannot get the RecyclerView in Frag B to display new data live. This is because the activity viewpager initializes both fragments at launch, meaning you can't call the onCreateView code again, I believe.
Communicating between two fragments through an Activity has been touched before on this site, but I found the best example to be this one:
(https://github.com/kylejablonski/InterfaceDemo),
which uses two interfaces, one to communicate from Frag A to Activity, and another one to communicate from Activity to Frag B. But I have a serious problem -
Currently, clicking both the "clear portfolio" and "add stock" to portfolio buttons in Frag A result in an empty screen in Frag B, which means something is being called yet new data is not being displayed/associated with the Adapter
Activity (https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ViewHolderActivity.java)
public class ViewHolderActivity extends AppCompatActivity implements CommunicateToActivity,CommunicateToFragment{
//Job of ViewHolderActivity is to allow swiping between list and MainFragment/Fragment
TabLayout tablayout;
ViewPager viewPager;
List<HistoricalQuote> historicaldata;
Bundle bundle;
Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_holder);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager =(ViewPager)findViewById(R.id.viewpager);
tablayout= (TabLayout)findViewById(R.id.tabs);
tablayout.setupWithViewPager(viewPager);
setupViewPager(viewPager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
//----------------------- Interface code-----------
#Override
public void communicateup(){
communicatedown();
//call communicate down STRAIGHT, since we call it from mainfrag
}
#Override
public void communicatedown(){
//This line works
ListFragment currentFragment =(ListFragment)adapter.instantiateItem(viewPager,1);
currentFragment.refreshUI();
}
private void setupViewPager(ViewPager viewPager) {
adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new MainFragment(), "Add Stock");
adapter.addFragment(new ListFragment(), "Portfolio");
viewPager.setAdapter(adapter);
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public Adapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Frag A (MainFragment)
(https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/MainFragment.java)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view =inflater.inflate(R.layout.content_main,container,false);
stocknames = new ArrayList<String>();
stocktickers = new ArrayList<String>();
tinyDB = new TinyDB(getContext());
/*
menu.setDisplayShowHomeEnabled(true);
//menu.setLogo("INSERT LOGO HERE");
menu.setDisplayUseLogoEnabled(true);
menu.setTitle(" Stock Selector");
*/
fetch =(Button) view.findViewById(R.id.fetchBtn);
enterID =(EditText)view.findViewById(R.id.enterID);
display =(TextView)view.findViewById(R.id.display);
mCalendar = Calendar.getInstance();
clear = (Button)view.findViewById(R.id.clearportfolio);
fetch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//TODO all the main page should do is add stocktickers and names to portfolio
//Fetch id and the dates
id =enterID.getText().toString();
/*to = Calendar.getInstance();
from = Calendar.getInstance();
to.setTime(dateto);
from.setTime(datefrom);
*/
FetchXDayData getData = new FetchXDayData();
getData.execute(id);
}
});
clear.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
tinyDB.clear();
recyclerinterface.communicateup();
}
});
return view;
}
//----------------------------INTERFACE CODE
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
recyclerinterface = (CommunicateToActivity) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement RecyclerUpdateInterface");
}
}
///-------End of Oncreate---------------------------------------------------------------
//Called by AsyncTask, moving result to main thread
public void moveResultToUI(Stock result){
this.stock = result;
Toast.makeText(getActivity(),"Stock "+stock.getName()+" successfully added to portofolio",Toast.LENGTH_LONG).show();
//reverse the list of course, stock names and tickrs to portfolio
stocknames.add(stock.getName());
stocktickers.add(stock.getSymbol());
/*DEBUG Test code, Test. 30012017 WORKS
for (int i =0;i<historicaldata.size();i++){
HistoricalQuote current = historicaldata.get(i);
Toast toast = Toast.makeText(this,current.getClose().toString(),Toast.LENGTH_SHORT);
toast.show();
}
*/
//
if (stock != null){
display.setText("Name: "+stock.getName() +"\n"+"Price: "+ stock.getQuote().getPrice()+"\n"+ "Change(%)"+stock.getQuote().getChangeInPercent());
/*SMA = getSMA(10);
decision=checkSimpleCrossover(SMA,stock.getQuote().getPrice().longValue());
decisionView.setText("SMA: " + SMA + "\n"+decision);
*/
tinyDB.putListString("names",stocknames);
tinyDB.putListString("tickers",stocktickers);
//call interface activity comming up to Activity, then down to next fragment
recyclerinterface.communicateup();
}else{
Toast error = Toast.makeText(getActivity(),"Network Problem",Toast.LENGTH_SHORT);
error.show();
}
}
Frag B (ListFragment)
(https://github.com/EXJUSTICE/Investr/blob/master/app/src/main/java/com/xu/investo/ListFragment.java)
public class ListFragment extends Fragment {
private HistoricalQuote[] hisstocks;
private Stock[] stocks;
private RecyclerView recyclerView;
private StockAdapter mAdapter;
public ArrayList<String> stocknames;
public ArrayList<String>stocktickers;
TinyDB tinyDB;
#Override
public void onCreate(Bundle savedInstanceState){
//exists only to set the options menu
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
//fetching arraylists
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_list, container, false);
//Convert the arraylist into an array for arrayadapter
stocknames = new ArrayList<String>();
stocktickers = new ArrayList<String>();
tinyDB = new TinyDB(getContext());
stocknames = tinyDB.getListString("names");
stocktickers= tinyDB.getListString("tickers");
if (!stocknames.isEmpty()){
for (int i =0;i<stocknames.size();i++){
Toast toast= Toast.makeText(getActivity(),stocknames.get(i),Toast.LENGTH_SHORT);
toast.show();
}
}
recyclerView = (RecyclerView)view.findViewById(R.id.recylerView);
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.HORIZONTAL));
//http://stackoverflow.com/questions/24618829/how-to-add-dividers-and-spaces-between-items-in-recyclerview
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
//layoutManager necessary because it positions views on screen, in this case linearly
if (stocknames.isEmpty() ||stocknames ==null){
recyclerView.setVisibility(View.GONE);
}else{
updateUI();
}
return view;
}
public void refreshUI(){
stocknames.clear();
stocktickers.clear();
stocknames = tinyDB.getListString("names");
stocktickers= tinyDB.getListString("tickers");
if (mAdapter == null) {
mAdapter = new StockAdapter(stocknames,stocktickers);
recyclerView.setAdapter(mAdapter);
} else {
recyclerView.invalidate();
mAdapter.notifyDataSetChanged();
}
}
public void updateUI() {
//updateUI must be called EXPLICITLY!
stocknames = tinyDB.getListString("names");
stocktickers= tinyDB.getListString("tickers");
if (mAdapter == null) {
mAdapter = new StockAdapter(stocknames,stocktickers);
recyclerView.setAdapter(mAdapter);
} else {
mAdapter.notifyDataSetChanged();
}
}
private class StockAdapter extends RecyclerView.Adapter<StockHolder>{
private ArrayList<String>stocknames;
private ArrayList<String>stocktickers;
public StockAdapter(ArrayList<String>names,ArrayList<String> tickers){
this.stocknames=names;
this.stocktickers=tickers;
}
#Override
public StockHolder onCreateViewHolder(ViewGroup parent, int viewType){
LayoutInflater layoutinflater = LayoutInflater.from(getActivity());
View view= layoutinflater.inflate(R.layout.row,parent,false);
return new StockHolder (view);
}
//Bind datato stockholder depending on position in arraylist
public void onBindViewHolder(StockHolder holder, int position){
String stockname = stocknames.get(position);
String stockticker =stocktickers.get(position);
holder.bindStock(stockname,stockticker);
}
#Override
public int getItemCount (){
return stocknames.size();
}
}
private class StockHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private String stockname;
private String stockticker;
private TextView nametextView;
private TextView tickertextView;
public StockHolder(View itemView){
super(itemView);
itemView.setOnClickListener(this);
nametextView =(TextView)itemView.findViewById(R.id.name);
tickertextView= (TextView)itemView.findViewById(R.id.ticker);
}
#Override
public void onClick(View v){
Intent launchGraph= new Intent(v.getContext(),GraphActivity.class);
launchGraph.putExtra("stockticker",stockticker);
launchGraph.putExtra("stockname",stockname);
startActivity(launchGraph);
//Animations?
}
//Actual binder method, maybe add a current
public void bindStock(String stocknom, String stocktick){
this.stockname=stocknom;
this.stockticker = stocktick;
nametextView.setText(stockname);
tickertextView.setText(stockticker);
}
}
Thanks in advance.
EDIT: Solved issue by creating a new adapter and linking it to new arraylists pulled from the TinyDB, thereby effectively swapping adapters.
Solved the issue by creating a whole new RecyclerView adapter, to which new arraylist data was binded to, and the whole recyclerview was then set to use this new adapter. All of this was done in a single step from FragA, using interfaces shown in the code in the solution.
Method shown below:
public void refreshUI(){
tinyDB = null;
tinyDB = new TinyDB(getContext());
newnames = tinyDB.getListString("names");
newtickers= tinyDB.getListString("tickers");
mAdapter = new StockAdapter(newnames,newtickers);
recyclerView.setAdapter(mAdapter);
}
This is my first application in Android Studio and I canĀ“t resolve this error, I need help, thanks.
E/RecyclerView: No adapter attached; skipping layout
E/RecyclerView: No adapter attached; skipping layout
MainActivity
public class MainActivity extends AppCompatActivity {
private ViewPager mPager;
private SlidingTabLayout mTabs;
private Toolbar toolbar;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//toolbar
toolbar= (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Sliding Tab
mPager = (ViewPager) findViewById(R.id.pager);
mTabs= (SlidingTabLayout) findViewById(R.id.tabs);
mPager.setAdapter(new MyAdapter(getSupportFragmentManager(),this));
mTabs.setDistributeEvenly(true);
mTabs.setCustomTabView(R.layout.tab_view, R.id.tabTeks);
mTabs.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
mTabs.setSelectedIndicatorColors(getResources().getColor(R.color.colorAccent));
mTabs.setViewPager(mPager);
}
My adapter
public class MyAdapter extends FragmentPagerAdapter {
private Context mContext;
private String[] titles ={"OVERVIEW","PORTOFOLIO","TEAM"};
int [] icons = new int []{R.mipmap.ic_adopcion, R.mipmap.ic_launcher, R.mipmap.ic_launcher};
private int heightIcon;
public MyAdapter(FragmentManager fm, Context c) {
super(fm);
mContext=c;
double scale=c.getResources().getDisplayMetrics().density;
heightIcon=(int)(30*scale+0.5f);
}
#Override
public Fragment getItem(int position) {
Fragment frag=null;
if (position==0){
frag = new OverviewFragment();
} else if(position==1){
frag= new TeamFragment();
} else if(position==2){
frag = new PortofolioFragment();
}
Bundle b = new Bundle();
b.putInt("position", position);
frag.setArguments(b);
return frag;
}
#Override
public int getCount() {
return titles.length;
}
#Override
public CharSequence getPageTitle(int position) {
Drawable d = mContext.getResources().getDrawable(icons[position]);
d.setBounds(0,0,heightIcon,heightIcon);
ImageSpan is = new ImageSpan(d);
SpannableString sp = new SpannableString(" ");
sp.setSpan(is,0,sp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return (sp);
}
ItemAdapter
public class ItemAdapter extends RecyclerView.Adapter<ItemHolder> {
private List<Perros> PerrosList;
public ItemAdapter(List<Perros> PerrosList){
this.PerrosList = PerrosList;
}
#Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, parent, false);
return new ItemHolder(itemView);
}
#Override
public void onBindViewHolder(ItemHolder holder, int position) {
Perros item = PerrosList.get(position);
holder.txtCelebName.setText(item.getName());
holder.txtCelebMovie.setText(item.getFamousMovie());
Picasso.with(holder.txtCelebName.getContext()).load(item.getProfilePhotoLocation()).into(holder.profileImage);
Picasso.with(holder.txtCelebName.getContext()).load(item.getImgsex()).into(holder.imgsex);
}
#Override
public int getItemCount() {
return PerrosList.size();
}
Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_overview, container, false);
//return inflater.inflate(R.layout.fragment_overview, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRequestQueue = MySingleton.getInstance().getRequestQueue();
array = new JsonObjectRequest(Request.Method.GET, url, "", new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
itemAdapter = new ItemAdapter(getPerros(response));
recyclerView.setAdapter(itemAdapter);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG,error.toString());
}
});
mRequestQueue.add(array);
return rootView;
//return inflater.inflate(R.layout.fragment_overview, container, false);
}
private List<Perros> getPerros(JSONObject jsonObject){
List<Perros> lista = new ArrayList<>();
try {
JSONArray array= jsonObject.getJSONArray("alumnos");
for (int i=0; i<array.length(); i++){
JSONObject objeto = array.getJSONObject(i);
Perros perro = new Perros();
perro.setName(objeto.getString("nombre"));
perro.setFamousMovie(objeto.getString("direccion"));
perro.setProfilePhotoLocation(img+objeto.getString("rutaimagen"));
perro.setImgsex(img+objeto.getString("sexo"));
lista.add(perro);
}
} catch (JSONException e) {
e.printStackTrace();
}
return lista;
}
You need to set the blank adapter before you get the data in ArrayAdapter in onCreate() method. First
of all put below line in ItemAdapter in getItemCount() method.
return (null != PerrosList ? PerrosList.size() : 0);
Change onCreateView code to this
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_overview, container, false);
//return inflater.inflate(R.layout.fragment_overview, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRequestQueue = MySingleton.getInstance().getRequestQueue();
itemAdapter = new ItemAdapter(new ArrayList<Perros>());
array = new JsonObjectRequest(Request.Method.GET, url, "", new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
itemAdapter.setData(getPerros(response));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG,error.toString());
}
});
mRequestQueue.add(array);
return rootView;
//return inflater.inflate(R.layout.fragment_overview, container, false);
}
And add this method in your Adapter code
void setData(List<Perros> data)
{
this.PerrosList.clear();
for(Perros p:data){
this.PerrosList.add(p);
}
notifyDataSetChanged();
}
It happens when you are not setting the adapter during the creation phase: call notifyDataSetChanged() when api response is getting
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
magazineAdapter = new MagazineAdapter(getContext(), null, this );
newClipRecyclerView.setAdapter(magazineAdapter);
magazineAdapter.notifyDataSetChanged();
APICall();
}
public void APICall() {
if(Response.isSuccessfull()){
mRecyclerView.setAdapter(mAdapter);
}
}
Just move setting the adapter into onCreate with an empty data and when you have the data call:
mAdapter.notifyDataSetChanged();
I'm trying to implement an activity with tabs in action bar and a view pager. I have the same fragment for every tab.
I need to update fragments after onCreateView is called, passing objects.
Pager adapter :
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter() {
super(getSupportFragmentManager());
}
#Override
public int getCount() {
return cat_pages.getList_categories().size();
}
#Override
public Fragment getItem(int position) {
Log.i("position fragment", "i = " + position);
final Handler uiHandler = new Handler();
int index = position;
final Category cat = cat_pages.getList_categories().get(index);
Log.i("position fragment", "name = " + cat.getName());
mCategoriesFragment = new ListPostFragment();
return mCategoriesFragment;
}
}
Fragment :
public class ListPostFragment extends Fragment {
// Layouts
private LinearLayout layout_loading;
public static GridView list_view_articles;
private TextView txt_nothing, txt_title;
// The list of headlines that we are displaying
private List<Post> mPostsList = new ArrayList<Post>();
private List<Post> list_posts = new ArrayList<Post>();
// The list adapter for the list we are displaying
private ArticlesAdapter mListAdapter;
private Category mCurrentCat;
Category clicked_cat;
String activity;
String title;
public ListPostFragment() {
super();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mListAdapter = new ArticlesAdapter(getActivity(), mPostsList);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_grid_posts, container, false);
layout_loading = (LinearLayout) rootView.findViewById(R.id.layout_loading);
list_view_articles = (GridView) rootView.findViewById(R.id.gridViewArticles);
txt_nothing = (TextView) rootView.findViewById(R.id.txt_no_result);
txt_title = (TextView) rootView.findViewById(R.id.txt_title);
Log.i("frag", "frag create view");
return rootView;
}
#Override
public void onStart() {
super.onStart();
list_view_articles.setAdapter(mListAdapter);
}
public void loadPosts(Category clicked_cat, List<Post> list_posts, String title) {
Log.i("frag", "frag load");
layout_loading.setVisibility(View.VISIBLE);
list_view_articles.setVisibility(View.GONE);
txt_title.setVisibility(View.GONE);
mPostsList.clear();
layout_loading.setVisibility(View.GONE);
if(list_posts != null){
mPostsList.addAll(list_posts);
if(mPostsList.size() > 0){
list_view_articles.setVisibility(View.VISIBLE);
txt_nothing.setVisibility(View.GONE);
}else{
list_view_articles.setVisibility(View.GONE);
txt_nothing.setVisibility(View.VISIBLE);
}
mListAdapter.notifyDataSetChanged();
}else{ // Nothing to display
list_view_articles.setVisibility(View.GONE);
txt_nothing.setVisibility(View.VISIBLE);
}
}
}
==> What I need to to call loadPosts(...) in PagerAdapter getItem(), once onCreateView has been called.
Any help is very appreciated.
You should pass your Category as an Extra to the fragment like so:
Bundle bundle = new Bundle();
bundle.putSerializable("CATEGORY", cat);
mCategoriesFragment.setArguments(bundle);
and then in onCreate() in the fragment you can read it using:
Bundle bundle = this.getArguments();
Category cat = (Category) bundle.getSerializable("CATEGORY");
// now you can call loadPosts()