I am trying to implement a sales app with 3 stages, whereby a user first adds the items, views the cart to checkout and prints a receipt. The first stage is done and works well. I am implementing this using one Activity with a tabbed layout and 3 fragments for each of the tabs.
On the activity for viewing the cart, I am using a RecyclerView which loads well when the activity is created, but once I add an item and try to view the list, there is no update. However, when I print the item list, the item has been added.
I have tried to update the RecyclerView using notifyDataSetChanged() but it gives me a null pointer exception. I have and tried several solutions but none has worked. Kindly assist.
Below is my code.
NewSaleActivity.java
public class NewSaleActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private ActivityNewSaleBinding binding;
DrawerLayout drawerLayout;
NavigationView navigationView;
TabLayout tabLayout;
Context context;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityNewSaleBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Toolbar toolbar = findViewById(R.id.new_sale_toolbar);
toolbar.setTitle(R.string.new_sale);
setSupportActionBar(toolbar);
drawerLayout = findViewById(R.id.new_sale_drawer);
navigationView = findViewById(R.id.new_sale_navigation);
navigationView.bringToFront();
navigationView.setNavigationItemSelectedListener(this);
navigationView.setCheckedItem(R.id.nav_sale);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();
context = getApplicationContext();
tabLayout = findViewById(R.id.tab_layout);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
viewPager = binding.viewPager;
viewPager.setAdapter(sectionsPagerAdapter);
viewPager.setOffscreenPageLimit(1);
TabLayout tabs = binding.tabLayout;
tabs.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
//When cart tab is selected
if(tab.getPosition() == 1) {
CartFragment cartFragment = new CartFragment();
cartFragment.loadItemsInCart();
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
Intent mainIntent = new Intent(NewSaleActivity.this, MainActivity.class);
startActivity(mainIntent);
finish();
break;
case R.id.nav_inventory:
Intent inventoryIntent = new Intent(NewSaleActivity.this, InventoryActivity.class);
startActivity(inventoryIntent);
finish();
break;
case R.id.nav_sale:
break;
case R.id.nav_logout:
UserLogout.userLogout(NewSaleActivity.this);
break;
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
}
CartFragment.java
public class CartFragment extends Fragment {
RecyclerView cartRecyclerView;
TextInputLayout grossTotalInput, discountInput, netTotalInput;
Button checkoutButton;
CartItemAdapter cartItemAdapter;
ArrayList<CartItem> cartItemList;
public CartFragment() {
// Required empty public constructor
}
public static CartFragment newInstance() {
CartFragment fragment = new CartFragment();
Bundle args = new Bundle();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
cartRecyclerView = view.findViewById(R.id.cart_recycler_view);
grossTotalInput = view.findViewById(R.id.gross_total_input);
discountInput = view.findViewById(R.id.discount_input);
netTotalInput = view.findViewById(R.id.net_total_input);
checkoutButton = view.findViewById(R.id.checkout_button);
Paper.init(requireContext());
cartItemList = Paper.book().read("cartItems", new ArrayList<CartItem>());
cartRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
cartItemAdapter = new CartItemAdapter(cartItemList);
cartRecyclerView.setAdapter(cartItemAdapter);
checkoutButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
checkoutOrder();
}
});
cartItemAdapter.notifyDataSetChanged();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_cart, container, false);
}
public void loadItemsInCart() {
ArrayList<CartItem> cartList = Paper.book().read("cartItems", new ArrayList<CartItem>());
for(CartItem cartItem : cartList) {
Log.d("cartItem", cartItem.getItemName());
}
cartItemAdapter.updateCartList(cartList);
Log.d("loadItemsInCart", "Load Items In Cart is triggered");
}
CartItemAdapter.java
public class CartItemAdapter extends RecyclerView.Adapter<CartItemAdapter.ViewHolder> {
private final ArrayList<CartItem> cartItems;
public CartItemAdapter(ArrayList<CartItem> cartItems) {
this.cartItems = cartItems;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView itemCode, itemName, quantity, price;
public ViewHolder(View itemView) {
super(itemView);
this.itemCode = itemView.findViewById(R.id.item_code);
this.itemName = itemView.findViewById(R.id.item_name);
this.quantity = itemView.findViewById(R.id.item_quantity);
this.price = itemView.findViewById(R.id.item_price);
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View cartListItem = layoutInflater.inflate(R.layout.add_to_cart_item, parent, false);
return new CartItemAdapter.ViewHolder(cartListItem);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.itemCode.setText(cartItems.get(position).getItemCode());
holder.itemName.setText(cartItems.get(position).getItemName());
holder.quantity.setText(cartItems.get(position).getQuantity().toString());
holder.price.setText(cartItems.get(position).getTotalAmount().toString());
}
#Override
public int getItemCount() {
return cartItems.size();
}
#SuppressLint("NotifyDataSetChanged")
public void updateCartList(ArrayList<CartItem> cartList) {
cartItems.clear();
this.cartItems.addAll(cartList);
notifyDataSetChanged();
}
}
The error message that I get is as below
java.lang.NullPointerException: Attempt to invoke virtual method 'void app.project.jsml_sales_app.adapters.CartItemAdapter.updateCartList(java.util.ArrayList)' on a null object reference
at app.project.jsml_sales_app.activities.fragments.CartFragment.loadItemsInCart(CartFragment.java:128)
at app.project.jsml_sales_app.activities.NewSaleActivity$1.onTabSelected(NewSaleActivity.java:78)
at com.google.android.material.tabs.TabLayout.dispatchTabSelected(TabLayout.java:1993)
at com.google.android.material.tabs.TabLayout.selectTab(TabLayout.java:1986)
Related
This question already has answers here:
recyclerview No adapter attached; skipping layout
(38 answers)
Closed 4 years ago.
Today I'm having this issue with my application; I want to say that I read almost ALL the other questions here on StackOverflow but nothing, always the same problem.
homepage.java (main class)
public class homepage extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homepage);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_homepage, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = null;
switch(getArguments().getInt(ARG_SECTION_NUMBER))
{
case 1:
rootView = inflater.inflate(R.layout.fragment_homepage, container, false);
break;
case 2:
rootView = inflater.inflate(R.layout.fragment_fibra, container, false);
break;
case 3:
rootView = inflater.inflate(R.layout.fragment_adsl, container, false);
break;
case 4:
rootView = inflater.inflate(R.layout.fragment_aiuto, container, false);
break;
}
return rootView;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 4 total pages.
return 4;
}
}
}
MyAdapter.java (default code from Android Studio Guide)
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>
{
private String[] mDataset;
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public MyViewHolder(TextView v) {
super(v);
mTextView = v;
}
}
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
TextView v = (TextView) LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mTextView.setText(mDataset[position]);
}
#Override
public int getItemCount() {
return mDataset.length;
}
}
And finally, one of the fragment that I'm using:
fibra.java
public class fibra extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
private RecyclerView recyclerView;
private MyAdapter adapter;
private LinearLayoutManager llm;
String [] prova={"prova1","prova2","prova2","prova2","prova2","prova2","prova2"};
public fibra() {
}
public static fibra newInstance(String param1, String param2) {
fibra fragment = new fibra();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.my_activity); (doesn't work "cannot resolve method")
recyclerView.setHasFixedSize(true); //per migliorare performance
llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(llm);
adapter = new MyAdapter(prova);
recyclerView.setAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_fibra, container, false);
return rootView;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
Here:
//setContentView(R.layout.my_activity); (doesn't work "cannot resolve method")
It's like inflating a layout inside an Activity which you already have onCreateView and in a Fragment.
Change the first codes to :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
Then, initialize RecyclerView inside onCreateView().
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_fibra, container, false);
// Here you should initialize RecyclerView and other widgets by rootView.findViewById and etc
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true); //per migliorare performance
llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(llm);
adapter = new MyAdapter(prova);
recyclerView.setAdapter(adapter);
return rootView;
}
You forget to add tablaylout.setupWithViewPager(mViewPager); in your homepage.java
I have a variable in MainActivity that I have successfully passed to StoriesActivity.
The problem is with getting it from there to StoriesFragment, which is a TabLayout tab.
I understand about Intents and Bundles but I'm not sure how they'd work in this instance.
This is StoriesActivity:
public class StoriesActivity extends AppCompatActivity {
//This is our tablayout
private TabLayout tabLayout;
//This is our viewPager
private ViewPager viewPager;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stories);
/* +++ START Intent +++ */
Bundle extras = getIntent().getExtras();
final int authorID = extras.getInt("author_id");
final String authorName = extras.getString("author_name");
Log.i("click", Integer.toString(authorID));
// this is successful
/* +++ END Intent +++ */
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(authorName);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new StoriesFragment(), "Stories");
adapter.addFragment(new CollectionsFragment(), "Collections");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(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);
}
}
}
And this is StoriesFragment (which doesn't work at the moment because it's not accessing the authorID variable from StoriesActivity):
public class StoriesFragment extends Fragment {
public StoriesFragment() {
// Required empty public constructor
}
private ListView storiesListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// link ListView object with XML ListView
storiesListView = (ListView) findViewById(R.id.stories_list_view);
// create new instance of DatabaseHelper
DatabaseHelper db = new DatabaseHelper(this);
// create list of stories through getAllStories method
List<Book> storyList = db.getAllStories(authorID);
// create new ArrayAdapter
ArrayAdapter<Book> arrayAdapter =
new ArrayAdapter<Book>(this, android.R.layout.simple_list_item_1, storyList);
// link ListView and ArrayAdapter
storiesListView.setAdapter(arrayAdapter);
Log.i("test", storyList.toString());
storiesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Book story = (Book) storiesListView.getItemAtPosition(i);
//Log.i("click", story);
Intent intent = new Intent(StoriesActivity.this, StoryBodyActivity.class);
intent.putExtra("story", story.getTitle());
startActivity(intent);
//Log.i("click", "That's a click!");
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_stories, container, false);
}
}
StoriesTabsAdapter:
public class StoriesTabsAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
public StoriesTabsAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
private String[] tabTitles = new String[]{"Stories", "Collections"};
// overriding getPageTitle()
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
StoriesFragment tab1 = new StoriesFragment();
return tab1;
case 1:
CollectionsFragment tab2 = new CollectionsFragment();
return tab2;
default:
return null;
}
}
#Override
public int getCount() {
return tabTitles.length;
}
}
Here is solution to your problem:
This is your activity:
public class StoriesActivity extends AppCompatActivity {
//This is our tablayout
private TabLayout tabLayout;
//This is our viewPager
private ViewPager viewPager;
private Toolbar toolbar;
private int authorID;
private String authorName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stories);
/* +++ START Intent +++ */
Bundle extras = getIntent().getExtras();
authorID = extras.getInt("author_id");
authorName = extras.getString("author_name");
Log.i("click", Integer.toString(authorID));
// this is successful
/* +++ END Intent +++ */
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(authorName);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(StoriesFragment.newInstance(authorID, authorName), "Stories");
adapter.addFragment(new CollectionsFragment(), "Collections");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(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);
}
}
}
This is your fragment:
public class StoriesFragment extends Fragment {
private int authorID;
private String authorName;
public StoriesFragment() {
// Required empty public constructor
}
public static StoriesFragment newInstance(int authorID, String authorName) {
Bundle args = new Bundle();
args.putInt("author_id", authorID);
args.putString("author_name", authorName);
StoriesFragment fragment = new StoriesFragment();
fragment.setArguments(args);
return fragment;
}
private ListView storiesListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Here is your arguments
authorID = getArguments().getInt("author_id");
authorName = getArguments().getString("author_name");
// link ListView object with XML ListView
storiesListView = (ListView) findViewById(R.id.stories_list_view);
// create new instance of DatabaseHelper
DatabaseHelper db = new DatabaseHelper(this);
// create list of stories through getAllStories method
List<Book> storyList = db.getAllStories(authorID);
// create new ArrayAdapter
ArrayAdapter<Book> arrayAdapter =
new ArrayAdapter<Book>(this, android.R.layout.simple_list_item_1, storyList);
// link ListView and ArrayAdapter
storiesListView.setAdapter(arrayAdapter);
Log.i("test", storyList.toString());
storiesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Book story = (Book) storiesListView.getItemAtPosition(i);
//Log.i("click", story);
Intent intent = new Intent(StoriesActivity.this, StoryBodyActivity.class);
intent.putExtra("story", story.getTitle());
startActivity(intent);
//Log.i("click", "That's a click!");
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_stories, container, false);
}
}
Hope it will help you.
for sending bundle data from your StoriesActivity
private void setupViewPager(ViewPager viewPager) {
Bundle bundle = new Bundle();
bundle.putString("your_key", "yourdata");
// set Fragmentclass Arguments
StoriesFragment fragStory = new StoriesFragment();
fragStory.setArguments(bundle);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(fragStory, "Stories");
adapter.addFragment(new CollectionsFragment(), "Collections");
viewPager.setAdapter(adapter);
}
I have problem when I cast the context in the FragmentAdapter of a Fragment. My app process is:
- When I click on navigation list item (Nav One) it will show the fragment with the recyclerview and cardview.
- When I click on the image of cardview list item I want get an action to show the Toast message or do something with a costom interface named (CustomCallBack).
This is my code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private ListView lvNavigation;
private DrawerLayout mDrawer;
private NavigationView mNavigation;
private LinearLayout llMianContain;
String[] navigation = new String[]{"Nav One","Nav Two", "Nav Three","Nav Four"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
lvNavigation = (ListView) findViewById(R.id.lv_listView);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mNavigation= (NavigationView) findViewById(R.id.navigation_view);
llMianContain = (LinearLayout) findViewById(R.id.ll_main_content);
setSupportActionBar(toolbar);
lvNavigation.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, navigation));
lvNavigation.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
replaceFragment(i);
lvNavigation.setItemChecked(i, true);
hideDrawer();
}
});
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.open, R.string.close);
mDrawer.setDrawerListener(toggle);
toggle.syncState();
}
private void replaceFragment(int position){
Fragment fragment = null;
switch (position){
case 0:
fragment = new OneFragment();
break;
case 1:
fragment = new TwoFragment();
break;
case 2:
fragment = new ThreeFragment();
break;
case 3:
fragment= new FourFragment();
break;
default:
fragment = new OneFragment();
break;
}
if(null!= fragment){
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.ll_main_content, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
private void hideDrawer(){
mDrawer.closeDrawer(GravityCompat.START);
}
private void showDrawer(){
mDrawer.openDrawer(GravityCompat.START);
}
#Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START))
hideDrawer();
else
super.onBackPressed();
}
}
OneFragment.java
public class OneFragment extends Fragment implements FragmentOneAdapter.CustomCallBack{
private ArrayList<ListItem> listItems;
private RecyclerView recyclerView;
private FragmentOneAdapter adapter;
public OneFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view =inflater.inflate(R.layout.fragment_one, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
LinearLayoutManager manager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(manager);
listItems = new ArrayList<>();
for(int i=0;i<40;i++){
listItems.add(new ListItem(R.drawable.ic_account_circle_black_48dp, "MY NAME "+ i));
}
adapter = new FragmentOneAdapter(listItems, getActivity());
recyclerView.setAdapter(adapter);
return view;
}
#Override
public void onProfileClick(int position) {
Toast.makeText(getActivity(), "position "+ position, Toast.LENGTH_SHORT).show();
}
}
FragmentAdapter.java
public class FragmentOneAdapter extends RecyclerView.Adapter<FragmentOneAdapter.FragmentOneViewHolder> {
private ArrayList<ListItem> listItems;
private Context context;
final CustomCallBack customCallBack;
public FragmentOneAdapter(ArrayList<ListItem> listItems, Context context){
this.listItems = listItems;
this.context = context;
this.customCallBack = (CustomCallBack) context;
}
#Override
public FragmentOneViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_one_item, parent,false);
FragmentOneViewHolder holder = new FragmentOneViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(FragmentOneViewHolder holder, int position) {
holder.tvName.setText(listItems.get(position).getName());
holder.ivProfile.setImageResource(listItems.get(position).getProfile());
}
#Override
public int getItemCount() {
return listItems.size();
}
class FragmentOneViewHolder extends RecyclerView.ViewHolder{
TextView tvName;
ImageView ivProfile;
LinearLayout llFooter;
public FragmentOneViewHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.tv_name);
ivProfile = (ImageView) itemView.findViewById(R.id.iv_profile);
llFooter= (LinearLayout) itemView.findViewById(R.id.ll_footer);
ivProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
customCallBack.onProfileClick(getAdapterPosition());
}
});
}
}
// MY Custom CallBack
interface CustomCallBack{
void onProfileClick(int position);
}
}
Hmm,
So your Fragment is implementing CustomCallBack interface
Why don't you just pass the Fragment object itself to the adapter?
for example, in the FragmentOneAdapter.java,
change:
public FragmentOneAdapter(ArrayList<ListItem> listItems, Context context) ===> public FragmentOneAdapter(ArrayList<ListItem> listItems, CustomCallBack callback)
then:
this.customCallBack = (CustomCallBack) context; ===> this.customCallBack = callback;
Obviously, now in OneFragment.java,
just pass 'this' as parameter as the Fragment itself is the CustomCallBack:
adapter = new FragmentOneAdapter(listItems, getActivity()); ===> adapter = new FragmentOneAdapter(listItems, this);
I have three tabs using the implementation below and they perform very well. When tab is changed the proper fragment is load and so on. The problem is that, when i get to the last tab and comeback to the first fragment, its like its oncreateview method is always triggered again running the other codes it in causing duplicates. Any help will be greatly appreciated.
//Activity on the tab is based
public class Dashboard extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private MyViewPagerAdapter myViewPagerAdapter;
private int[] tabIcon = {R.drawable.ic_home, R.drawable.ic_message, R.drawable.ic_person};
android.support.v7.widget.Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dashboard);
//Toolbar
toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//ViewPager
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
//Tablayout
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(0).setIcon(tabIcon[0]);
tabLayout.getTabAt(1).setIcon(tabIcon[1]);
tabLayout.getTabAt(2).setIcon(tabIcon[2]);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
switch(tab.getPosition()) {
case 0:
viewPager.setCurrentItem(0);
toolbar.setTitle("Home");
break;
case 1:
viewPager.setCurrentItem(1);
toolbar.setTitle("Messages");
break;
case 2:
viewPager.setCurrentItem(2);
toolbar.setTitle("Profile");
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void setupViewPager(ViewPager viewPager){
myViewPagerAdapter = new MyViewPagerAdapter(getSupportFragmentManager());
myViewPagerAdapter.addFragments(new CategoryFragment(), "Categories");
myViewPagerAdapter.addFragments(new MessagesFragment(), "Messages");
myViewPagerAdapter.addFragments(new ProfileFragment(), "Profile");
viewPager.setAdapter(myViewPagerAdapter);
}
//View Pager Adapter
public class MyViewPagerAdapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragments = new ArrayList<>();
ArrayList<String> tabTitles = new ArrayList<>();
public void addFragments(Fragment fragments, String titles){
this.fragments.add(fragments);
this.tabTitles.add(titles);
}
public MyViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
//return tabTitles.get(position);
return null;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
}
//Main first fragment code
public class CategoryFragment extends Fragment {
private DBHandler dbHandler;
private ListView listView;
private ListAdapter adapter;
ArrayList<Categories> categoriesList = new ArrayList<Categories>();
public CategoryFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
//Setting up the basic categories
dbHandler = new DBHandler(view.getContext());
//Get Categories from database
final Cursor cursor = dbHandler.getCategories(0);
if (cursor != null) {
if(cursor.moveToFirst()){
do{
Categories categories = new Categories();
categories.set_id(cursor.getInt(0));
categories.set_categoryname(cursor.getString(2));
categories.set_categoriescaption(cursor.getString(3));
categoriesList.add(categories);
}while (cursor.moveToNext());
}
cursor.close();
}
listView = (ListView) view.findViewById(R.id.categories);
adapter = new CategoryAdapter(view.getContext(), R.layout.cursor_row, categoriesList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Integer cid = (int) (long) adapter.getItemId(position);
TextView categoryname = (TextView) view.findViewById(R.id.cursor);
String cname = categoryname.getText().toString();
Intent i = new Intent(view.getContext(), CategoryList.class);
i.putExtra("categoryname", cname);
i.putExtra("categoryid", cid);
startActivity(i);
}
}
);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
So when i swipe back here from the last tab. OncreateView runs again. How can i handle that and prevent duplicates. Thank you
By defaults ViewPager retains only 1 page in the view hierarchy in an idle state.So when you swipe to third tab the viepager destroys the first tab in order to retain the second one.
To solve this issue add this line
viewPager.setOffscreenPageLimit(3);
after you set your adapter.
Check here the documentation for more
This is my Main Activity
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
TabLayout tablayout;
#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.
mViewPager = (ViewPager) findViewById(R.id.container);
tablayout = (TabLayout) findViewById(R.id.tablayout);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mSectionsPagerAdapter.addFragments(new UanNumbersFragment(),"UAN");
mSectionsPagerAdapter.addFragments(new BlankFragment(),"Emergency");
mViewPager.setAdapter(mSectionsPagerAdapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragments = new ArrayList<>();
ArrayList<String> tabtitles= new ArrayList<>();
public void addFragments (Fragment fragments,String tabtitles)
{
this.fragments.add(fragments);
this.tabtitles.add(tabtitles);
}
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return tabtitles.get(position);
}
}
}
This is my Fragment which i want to show in tabs
public class UanNumbersFragment extends Fragment {
public UanNumbersFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
This is my other Fragment for 2nd tab
public class BlankFragment extends Fragment {
public BlankFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank2, container, false);
}
}
Use PagerSlidingTabStrip library for this problem i was also facing this problem and now it is working for tab and mobile.
Then you may want to follow the amazing tutorial here at http://www.androidhive.info/2015/09/android-material-design-working-with-tabs/ because, that is step wise step, and no confusion will be there..
And regarding json, you can do,
JSONArray jsonArray = new JSONArray("keyName");
for (int i = 0, len = jsonArray.length(); i < len; i++) {
JSONObject entry = jsonArray.getJSONObject(i);
String a = entry.getString("a");
String b = entry.getString("b");
}
and then populate it into the listview using the base adapter..