I have a ViewPager with two Fragments with RecyclerViews that show Locations and Items. Each location contains different items. Now I want to update the recyclerView inside ItemsFragment when a location is selected in LocationsFragment. I set onClick method to location element to update the activeLocation field but I don't know how to refresh the data in items' recyclerView.
I would need to supply a new List object I get from getItems() into the adapter, but the adapter is null whenever ItemsFragment loses focus or make it so the fragment is recreated every time the activeLocation changes.
The only time it refreshes now is when the ItemsFragment's onCreateView is called. The list updates, because a new ItemAdapter is created and getItems() is called inside constructor. But this only happens when I scroll to 4th tab and back, so that the itemsFragment (2nd) is cleared from memory and reloaded.
Activity:
public class MainActivity extends AppCompatActivity implements MaterialTabListener {
MaterialTabHost tabHost;
ViewPager pager;
ViewPagerAdapter adapter;
private final int[] icons = {R.drawable.icon_locations, R.drawable.icon_items};
public static Location activeLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
Realm.setDefaultConfiguration(new RealmConfiguration.Builder(this).build());
Realm realm = Realm.getDefaultInstance();
activeLocation = realm.where(Location.class).findFirst();
pager = (ViewPager) findViewById(R.id.view_pager);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
tabHost = (MaterialTabHost) this.findViewById(R.id.materialTabHost);
for (int i = 0; i < adapter.getCount(); i++) {
tabHost.addTab(
tabHost.newTab()
.setIcon(ResourcesCompat.getDrawable(getResources(), icons[i], null)).setTabListener(this)
);
}
}
ViewPager:
class ViewPagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES = {"Locations", "Items"};
private final int[] ICONS = {R.drawable.icon_locations, R.drawable.icon_items};
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case FragmentType.LOCATIONS: {
fragment = LocationsFragment.newInstance();
break;
}
case FragmentType.ITEMS: {
fragment = ItemsFragment.newInstance();
break;
}
}
return fragment;
}
}
LocationsFragment:
public class LocationsFragment extends Fragment {
private RecyclerView recyclerView;
private LocationAdapter adapter;
public static LocationsFragment newInstance() {
return new LocationsFragment();
}
public LocationsFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_locations, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.locations_recycler_view);
adapter = new LocationAdapter(getActivity(), getLocations());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return layout;
}
public List<Location> getLocations() {
List<Location> locations;
Log.d("null act", getActivity() == null? "null" : "not null");
Realm realm = Realm.getDefaultInstance();
locations = realm.where(Location.class).findAll();
return locations;
}
}
LocationAdapter:
public class LocationAdapter extends RecyclerView.Adapter<LocationAdapter.LocationHolder> {
List<Location> list = Collections.emptyList();
Context context;
private LayoutInflater inflater;
public LocationAdapter(Context context, List<Location> list) {
this.list = list;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public LocationHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.card_location, parent, false);
return new LocationHolder(view);
}
#Override
public void onBindViewHolder(final LocationHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("clicked", "Location " + location.getId() + " " + location.getName() + " pressed");
if (context instanceof MainActivity) {
MainActivity mainActivity = (MainActivity) context;
MainActivity.activeLocation = location;
mainActivity.setFragment(1); //this changes the title on actionBar and tab highlights
}
}
});
}
ItemsFragment and ItemAdapter are the same as Locations.
Related
As you can see from the title I'm a little confused on how to resolve my problem. I have an activity that use Tabs to switch between two fragments that contain one list eache one. The list have the same adapter, and in every list there's a button that refresh the two lists.
Here's my MainActivity.class:
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
public static TreeSet<Task> tasksTODO = new TreeSet<>();
public static TreeSet<Task> tasksDONE = new TreeSet<>();
private TabLayout tabs;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = findViewById(R.id.container);
tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(mViewPager);
tabs.setSelectedTabIndicatorColor(Color.parseColor("#FFFFFF"));
addTasks();
}
#Override
protected void onResume() {
super.onResume();
addTasks();
}
private void setupViewPager(ViewPager vp) {
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mSectionsPagerAdapter.addFragment(new ShowTodoTasks(), "todo");
mSectionsPagerAdapter.addFragment(new ShowDoneTasks(), "done");
vp.setAdapter(mSectionsPagerAdapter);
}
public void addTasks() {
tasksDONE.add(new Task("Number 1", "pepin", "", "Description 1", 1));
tasksDONE.add(new Task("Number 2", "pepin", "", "Description 2", 1));
tasksDONE.add(new Task("Number 3", "pepin", "", "Description 3", 1));
tasksTODO.add(new Task("Number 4", "pepin", "", "Description 4", 1));
setupViewPager(mViewPager);
}
}
Here's my TaskAdapter:
public class TaskAdapter extends BaseAdapter {
protected Context context;
protected ArrayList<Task> items;
private ImageView edit;
private CheckBox checked;
Task dir;
private TextView title, comment, description, date;
public TaskAdapter(Context context, ArrayList<Task> items) {
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int position, View view, ViewGroup viewGroup) {
LayoutInflater inf = (LayoutInflater) viewGroup.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.task_item_template, null);
edit = (ImageView) view.findViewById(R.id.item_edit);
checked = (CheckBox) view.findViewById(R.id.item_done);
final View finalView = view;
dir = items.get(position);
int priority = dir.getPriority();
if (priority == 1) {
view.setBackgroundResource(R.drawable.major_prior_task_border);
}
if (priority == 2) {
view.setBackgroundResource(R.drawable.medium_prior_task_border);
}
if (priority == 3) {
view.setBackgroundResource(R.drawable.minor_prior_task_border);
}
title = view.findViewById(R.id.item_title);
title.setText(dir.getTitle());
comment = view.findViewById(R.id.tv_comment);
comment.setText(dir.getComment());
description = view.findViewById(R.id.item_description);
description.setText(dir.getDescription());
date = view.findViewById(R.id.item_date);
date.setText(dir.getCreationDate());
return view;
}
}
And here are my Fragments:
public class ShowDoneTasks extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_show_done_tasks, container, false);
setup(MainActivity.tasksDONE,v);
return v;
}
#Override
public void onStart() {
super.onStart();
}
private void setup(TreeSet<Task> tasks, View v) {
ListView lv = v.findViewById(R.id.lv_tasks_done);
ArrayList<Task> tareasDone = new ArrayList<>(tasks);
TaskAdapter adapter = new TaskAdapter(v.getContext(), tareasDone);
lv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
And the other one:
public class ShowTodoTasks extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_show_todo_tasks, container, false);
setup(MainActivity.tasksTODO,v);
return v;
}
private void setup(TreeSet<Task> tasks, View v) {
ListView lv = v.findViewById(R.id.lv_tasks_todo);
ArrayList<Task> tareasTodo = new ArrayList<>(tasks);
TaskAdapter adapter = new TaskAdapter(v.getContext(), tareasTodo);
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
}
What I want is this: when you click on the checkBox that's in TaskAdapter i want to refresh the list. I tried using adapter.notifyDataSetChanged() in the fragments but it dosn't seem to work.
Any ideas?
Can not implement so: if tap to image in MainActivity - this image has to open in PreviewActivity full screen and there I can make scroll right and left use ViewPager to browse the next or previous image in the array. Now, when i tap to image, and if use in PageFragment - resultView.setImageResource(pageNumber); - then always open firts image in my array, and if use resultView.setImageURI(source); - then open true image but if swipe - always show this one image.
PageFragment - probably in this class something wrong
public class PageFragment extends Fragment {
private static final String ARGUMENT_PAGE_NUMBER = "id_test";
private int pageNumber;
private Uri source;
static PageFragment newInstance(int page) {
PageFragment pageFragment = new PageFragment();
Bundle arguments = new Bundle();
arguments.putInt(ARGUMENT_PAGE_NUMBER, page);
pageFragment.setArguments(arguments);
return pageFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = getActivity().getIntent();
pageNumber = i.getExtras().getInt("id_test");
source = Uri.parse("android.resource://com.test.nico/drawable/" + Images.loadImages[pageNumber]);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view_pager, null);
ImageView resultView = (ImageView) view.findViewById(R.id.result_image);
// resultView.setImageURI(source);
pageNumber = getArguments().getInt(ARGUMENT_PAGE_NUMBER);
resultView.setImageResource(pageNumber);
return view;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private Context mContext;
private RecyclerView mRecyclerView;
private ImageAdapter mImageAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = getApplicationContext();
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mImageAdapter = new ImageAdapter(mContext, Images.loadImages);
mLayoutManager = new GridLayoutManager(this, 2);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mImageAdapter);
}
}
PreviewActivity
public class PreviewActivity extends FragmentActivity {
private ViewPager viewPager;
private PagerAdapter pagerAdapter;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);
viewPager = (ViewPager) findViewById(R.id.preview_pager);
pagerAdapter = new PreviewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
}
}
ImageAdapter
class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.Holder> {
private int[] mItemList;
private Context mContext;
ImageAdapter(Context context, int[] itemList) {
this.mContext = context;
this.mItemList = itemList;
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_list, null);
return new Holder(layoutView);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
Picasso.with(mContext).load(Images.loadImages[position]).placeholder(R.drawable.ic_stub).resize(400, 750).into(holder.view);
}
#Override
public int getItemCount() {
return this.mItemList.length;
}
class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView view;
Holder(View itemView) {
super(itemView);
mContext = itemView.getContext();
view = new ImageView(mContext);
view = (ImageView) itemView.findViewById(R.id.recycler_view);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
final Intent intent = new Intent(mContext, PreviewActivity.class);
intent.putExtra("id_test", getAdapterPosition());
mContext.startActivity(intent);
}
}
}
PreviewPagerAdapter
class PreviewPagerAdapter extends FragmentStatePagerAdapter {
private int imagesCount = Images.loadImages.length;
private int[] images = Images.loadImages;
PreviewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return imagesCount;
}
#Override
public Fragment getItem(int position) {
return PageFragment.newInstance(images[position]);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
In your PreviewActivity you have to "jump" to the position you passed.
viewpager.setCurrentItem(getIntent().getExtras().getInt("id_test"));
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);
}
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..
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()