In my MainActivity I derive an arrayList of data. The trick here is that I am trying to rearrange this data Collection in a listview in different ways according to the tab that is selected for example (alphabetically, chronologically etc) I have the code that does that.
Below is my main activity.
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private FloatingActionButton fab;
private final int PICK = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fp_get_Android_Contacts();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// 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);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
// calling OnActivityResult with intenet And Some conatct for Identifie
startActivityForResult(intent, PICK);
}
});
}
public class Android_Contact {
public String android_contact_Name = "";
public String android_contact_TelefonNr = "";
public int android_contact_ID = 0;
}
public void fp_get_Android_Contacts() {
ArrayList<Android_Contact> arrayListAndroidContacts = new ArrayList<Android_Contact>();
Cursor cursor_Android_Contacts = null;
ContentResolver contentResolver = getContentResolver();
try {
cursor_Android_Contacts = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
} catch (
Exception ex
)
{
Log.e("Error on contact", ex.getMessage());
}
if (cursor_Android_Contacts.getCount() > 0)
{
while (cursor_Android_Contacts.moveToNext()) {
Android_Contact android_contact = new Android_Contact();
String contact_id = cursor_Android_Contacts.getString(cursor_Android_Contacts.getColumnIndex(ContactsContract.Contacts._ID));
String contact_display_name = cursor_Android_Contacts.getString(cursor_Android_Contacts.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
android_contact.android_contact_Name = contact_display_name;
int hasPhoneNumber = Integer.parseInt(cursor_Android_Contacts.getString(cursor_Android_Contacts.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
Cursor phoneCursor = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI
, null
, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"
, new String[]{contact_id}
, null);
while (phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
android_contact.android_contact_TelefonNr = phoneNumber;
}
phoneCursor.close();
}
arrayListAndroidContacts.add(android_contact);
}
Collections.reverse(arrayListAndroidContacts);
ListView listView_Android_Contacts = (ListView) findViewById(R.id.listview_Android_Contacts);
Adapter_for_Android_Contacts adapter = new Adapter_for_Android_Contacts(this, arrayListAndroidContacts);
listView_Android_Contacts.setAdapter(adapter);
}
}
public class Adapter_for_Android_Contacts extends BaseAdapter {
Context mContext;
List<Android_Contact> mList_Android_Contacts;
public Adapter_for_Android_Contacts(Context mContext, List<Android_Contact> mContact) {
this.mContext = mContext;
this.mList_Android_Contacts = mContact;
}
public int getCount() {
return mList_Android_Contacts.size();
}
public Object getItem(int position) {
return mList_Android_Contacts.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(mContext, R.layout.contactlist_android_items, null);
TextView textview_contact_Name = (TextView) view.findViewById(R.id.textview_android_contact_name);
textview_contact_Name.setText(mList_Android_Contacts.get(position).android_contact_Name);
view.setTag(mList_Android_Contacts.get(position).android_contact_Name);
return view;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Tab2AZ tab2 = new Tab2AZ();
return tab2;
case 1:
Tab1Recents tab1 = new Tab1Recents();
return tab1;
case 2:
Tab3Location tab3 = new Tab3Location();
return tab3;
case 3:
Tab4Groups tab4 = new Tab4Groups();
return tab4;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "A-Z";
case 1:
return "RECENT";
case 2:
return "LOCATION";
case 3:
return "TAGS";
}
return null;
}
}
}
To save you time the fp_get_Android_Contacts() method grabs the arraylist, then uses the adapter to put the content in the listview that is in the main activity xml. The result is that all the tabs visually display the same view. (Because the MainActivity's Listview is covering the fragment's listviews) I'm really just trying to get the content retrieved from the fp_get_Android_Contacts() method to display on one fragment at a time. Ive looked into using bundles, parcelables, intents and recently interfaces however successful implementation has been tough to achieve given my experience level perhaps. Would appreciate a specific approach instead of a reference to read something as I have done a lot of research and tried many things already.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.tab1_recent, container, false);
return rootView;
}
}
Create Interface
public interface FragmentListener {
void setArrayListAndroidContacts(List<Android_Contact> contacts);
List<Android_Contact> getArrayListAndroidContacts();
}
Let your MainActivity implement this interface
public class MainActivity extends AppCompatActivity implements FragmentListener {
//global field
private List<Android_Contact> arrayListAndroidContacts;
...
//your code
...
//override methods of interface
#Override
void setArrayListAndroidContacts(List<Android_Contact> contacts){
this.arrayListAndroidContacts = contacts;
}
#Override
List<Android_Contact> getArrayListAndroidContacts(){
return this.arrayListAndroidContacts;
}
Your fragment
public class YourFragment extends Fragment{
private FragmentListener mListener;
...
//in onCreateView
//this will give you list
mListener.getArrayListAndroidContacts();
....
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentListener) {
mListener = (FragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentListener");
}
}
}
Another method is just create public getter setter of arrayListAndroidContacts in MainActivity and in your fragment use (MainActivity getActivity()).getArrayListAndroidContacts() to get the list. I would prefer interface method because of reusability.
Also why create viewpager, fragments if you want to rearrange data by a filter selection(sort by alpha,chrono) without any view changes.
Just add filter menu actions in floatingmenu/toolbarsidemenu, recyclerview(any list view) and customadapter for it in Mainactivity. Depending on the filter selection reorder your contacts list and notifydatasetchanged will do all your work.
Go for tabs if you want to have category of contacts like favorites, business etc.. to be displayed in single screen.
Suggestion:-
Kindly separate your custom BaseAdapter code from MainActivity for better source code maintenance .
You should be having multiple tabs and corresponding Fragments for those tabs. Right ?
I can not find that in your code.
For every fragment generate a separate .xml file and create separate listview in each fragment and pass the data in each fragment accordingly. And you are done.
e.g., for alphabetically : Create fragment AlphabetSortFragment and for the same create a .xml file and a listview or recycler view in it.
Related
I have navigation drawer used to navigate through my application.
When I switch to fragment with ViewPagers containing three ListViews, everything is displayed normally.
The problem appears when I switch to another fragment, and then go back to my ListViews. Everything is empty.
Video with a problem:
https://youtu.be/hsZAGaAG_vs
Code of my Fragment containing ViewPagers:
public class PlayerListFragment extends Fragment {
private class RolePagerAdapter extends FragmentPagerAdapter {
public RolePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new SniperFragment();
case 1:
return new RiflerFragment();
case 2:
return new IglFragment();
}
return null;
}
#Override
public int getCount() { // 3 pages
return 3;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getActivity().getResources().getText(R.string.sniper_tab);
case 1:
return getActivity().getResources().getText(R.string.riflers_tab);
case 2:
return getActivity().getResources().getText(R.string.igls_tab);
}
return null;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_player_list, container, false);
}
#Override
public void onStart() {
super.onStart();
// setup viewpager
RolePagerAdapter adapter = new RolePagerAdapter(getActivity().getSupportFragmentManager());
ViewPager pager = getActivity().findViewById(R.id.pager);
pager.setAdapter(adapter);
// setup tablayout
TabLayout tabLayout = getActivity().findViewById(R.id.tabs);
tabLayout.setupWithViewPager(pager);
// hide default toolbar and set new
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
Toolbar listToolbar = getActivity().findViewById(R.id.player_list_toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(listToolbar);
DrawerLayout drawerLayout = getActivity().findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
getActivity(),
drawerLayout,
listToolbar,
R.string.nav_open_drawer,
R.string.nav_close_drawer);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
}
Code of my fragment containing listview:
public class SniperFragment extends AbstractRoleListFragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
new SetupAdapterTask().execute(Role.Sniper);
}
}
Code of parent class of that fragment:
public abstract class AbstractRoleListFragment extends ListFragment {
SQLiteDatabase db;
Cursor cursor;
protected class SetupAdapterTask extends AsyncTask<Role, Void, SimpleCursorAdapter> {
#Override
protected SimpleCursorAdapter doInBackground(Role... role) {
SQLiteOpenHelper helper = new MyDatabaseHelper(getActivity());
try {
db = helper.getReadableDatabase();
cursor = db.query("PLAYERS",
new String[]{"_id", "NAME"}, "ROLE = ?",
new String[]{role[0].toString()},
null, null, null);
return new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1,
cursor,
new String[]{"NAME"},
new int[] {android.R.id.text1},
0);
} catch (SQLiteException e) {
Log.e("ERR", "Error while setting up adapter in SniperFragment", e);
return null;
}
}
#Override
protected void onPostExecute(SimpleCursorAdapter adapter) {
if (adapter != null) {
setListAdapter(adapter);
} else {
Toast.makeText(getActivity(), "Database unavailable", Toast.LENGTH_SHORT)
.show();
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
cursor.close();
db.close();
}
}
I tried to change code filling my listview with data to another method like onResume, onStart but none worked
I have a main activity which shows 3 fragments inside View Pagers with tabs.
mainActivity.java
public class mainActivity extends AppCompatActivity {
globalVariableActivity variable = new globalVariableActivity();
private APIService mAPIService;
private TextView mResponseTv;
private RecyclerView recyclerView;
private Token token = new Token("","","");
private Gson gson = new Gson();
private Context context=mainActivity.this;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//check if token is still active
String current_token=token.getToken(context);
MyFirebaseInstanceIDService Fcm= new MyFirebaseInstanceIDService();
Fcm.onTokenRefresh(context,current_token);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
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 BeritaFragment(), "Berita");
adapter.addFragment(new DiskusiFragment(), "Diskusi");
adapter.addFragment(new PesanFragment(), "Pesan");
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) {
//Toast.makeText(context,"Item " + position + " shown.", Toast.LENGTH_SHORT).show();
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) {
Toast.makeText(context,"Position : " + position + " Title : "+ mFragmentTitleList.get(position) + " shown.", Toast.LENGTH_SHORT).show();
return mFragmentTitleList.get(position);
}
}
interface LyfecycleListener {
void onCreatedView();
}
here's the first fragment code
beritaFragment.java
public class BeritaFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private APIService mAPIService = APIUtils.getAPIService();;
private Gson gson = new Gson();
private TextView createdAtText;
private TextView judulText;
private ImageView imageView;
private RecyclerView mRecyclerView;
private ListAdapter mListadapter;
private ArrayList<DataBerita> list_berita= new ArrayList<>();
private OnFragmentInteractionListener mListener;
public BeritaFragment() {
}
// TODO: Rename and change types and number of parameters
public static BeritaFragment newInstance(String param1, String param2) {
BeritaFragment fragment = new BeritaFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getBeritaTask getBerita= new getBeritaTask();
try {
Log.d("berita :", "On create 1");
getBerita.execute().get(10000, TimeUnit.MILLISECONDS);
Log.d("berita :", "On create 2");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_berita, container, false);
Log.d("Berita","On create view");
Toast.makeText(getActivity() ,"Berita Fragment onCreateView", Toast.LENGTH_SHORT).show();
ArrayList<DataBerita> data_berita;
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
judulText = (TextView)view.findViewById(R.id.summary_judul);
createdAtText = (TextView)view.findViewById(R.id.created_at);
//imageView = (ImageView)view.findViewById(R.id.gambar);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
//data_berita=getBeritaList();
Log.d("Berita","1");
Log.d("Berita List : ", list_berita.toString());
Log.d("Berita","3");
mListadapter = new ListAdapter(list_berita);
mRecyclerView.setAdapter(mListadapter);
//Log.d("Berita view :", view.toString());
return view;
}
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder>
{
private ArrayList<DataBerita> dataList;
public ListAdapter(ArrayList<DataBerita> data)
{
this.dataList = data;
}
public class ViewHolder extends RecyclerView.ViewHolder
{
TextView judulText;
TextView waktuText;
ImageView gambarView;
public ViewHolder(View itemView)
{
super(itemView);
this.judulText = (TextView) itemView.findViewById(R.id.summary_judul);
this.waktuText = (TextView) itemView.findViewById(R.id.created_at);
//this.gambarView = (ImageView) itemView.findViewById(R.id.gambar);
}
}
#Override
public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.berita_list_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ListAdapter.ViewHolder holder, final int position)
{
Uri ImageURI=Uri.parse(dataList.get(position).getGambar_utama());
holder.judulText.setText(dataList.get(position).getSummary_judul());
holder.waktuText.setText(dataList.get(position).getCreated_at());
//holder.gambarView.setImageURI(ImageURI);
holder.itemView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(getActivity(), "Item " + position + " is clicked.", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount()
{
return dataList.size();
}
}
private class getBeritaTask extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
Log.d("Berita","2.1");
}
protected Void doInBackground(Void... voids) {
mAPIService.getBeritaList().enqueue(new Callback<Berita>() {
#Override
public void onResponse(Call<Berita> call, Response<Berita> response) {
list_berita = new ArrayList<>();
DataBerita data_berita = new DataBerita("","","","");
String id_berita;
String judul;
String gambar_utama;
String created_at;
Log.d("Berita","2.2");
if(response.isSuccessful()) {
Berita body = gson.fromJson(response.body().toString(),Berita.class);
for (int i = 0; i < body.getList_berita().getData().size(); i ++) {
id_berita=body.getList_berita().getData().get(i).getId_berita();
judul=body.getList_berita().getData().get(i).getSummary_judul();
gambar_utama=body.getList_berita().getData().get(i).getGambar_utama();
created_at=body.getList_berita().getData().get(i).getCreated_at();
data_berita = new DataBerita(id_berita,judul,gambar_utama,created_at);
list_berita.add(data_berita);
}
Log.d("Berita List",list_berita.toString());
}else{
Log.d("Berita", "Fail");
}
}
#Override
public void onFailure(Call<Berita> call, Throwable t) {
Log.d("Berita Fail", t.getMessage());
}
});
return null;
}
}
here's the 2nd and 3rd fragment (these 2 fragments are still mostly empty, with code for toast and log only for now)
DiskusiFragment.java
public class DiskusiFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public DiskusiFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static DiskusiFragment newInstance(String param1, String param2) {
DiskusiFragment fragment = new DiskusiFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Toast.makeText(getActivity() ,"Diskusi Fragment onCreateView", Toast.LENGTH_SHORT).show();
return inflater.inflate(R.layout.fragment_diskusi, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
here's the problem,
fragment onCreateView function seems to be called on / in the wrong fragment.
when I start the app here's what happened :
Item position 0 , 1, and 2 is called
1st fragment on create view is called, and 2nd fragment on create view is called immediately
what happens next, depends on what I do :
when I change from 1st fragment => 2nd fragment, 3rd fragment on create view is called
when I change from 1st fragment => 3rd fragment, 3rd fragment on create view is called
when I switch from 2nd fragment => 1st fragment, no fragment on create view called
when I switch from 2nd fragment => 3rd fragment, no fragment on create view called
when I switch from 3rd fragment => 2nd fragment, no fragment on create view called (or sometimes 1st fragment on create view is called)
when I change from 3rd fragment => 1st fragment, 1st fragment on create view called
is this what suppose (in regard to onCreateView function is called on the wrong fragment) to happen?
if not, where did I code wrong?
Thank you very much
*EDIT : this behaviour is normal, I'm really new to android. Very sorry for the inconvenience guys
The FragmentPagerAdapter keeps additional fragments, besides the one shown, in the resumed state.
If you want to initialize stuff in the fragment you should do it when
OnCreate is called.
Anything that is related to the UI been loaded properly should happen on
onViewCreated
In addition, if you want to receive more information about how to handle fragments inside a ViewPager
#Shreyas Shetty answered it really well on this thread
What do you mean by "wrong" fragment? View pager creates next fragment prior to navigating to it to make the transition smooth and quick. And when the fragment is created its lifecycle methods are called accordingly, there's nothing wrong with this behaviour. If you want to perform some action when the user swipes to specific fragment in your view pager, you can use OnPageChangeListener.
Hi I want to send the data ArrayList<Division> to Fragment class ListContentFragment.
In MainActivity I am making a network call to get the data(JSON) and then parsing it to create ArrayList<Division>, now i want to populate the list view with the data i received (now in ArrayList<Division>)
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Adding Toolbar to Main screen
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Setting ViewPager for each Tabs
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
// Set Tabs inside Toolbar
TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
// Create Navigation drawer and inlfate layout
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
// Adding menu icon to Toolbar
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
VectorDrawableCompat indicator
= VectorDrawableCompat.create(getResources(), R.drawable.ic_menu, getTheme());
indicator.setTint(ResourcesCompat.getColor(getResources(),R.color.white,getTheme()));
supportActionBar.setHomeAsUpIndicator(indicator);
supportActionBar.setDisplayHomeAsUpEnabled(true);
}
// Set behavior of Navigation drawer
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Set item in checked state
menuItem.setChecked(true);
// TODO: handle navigation
Toast.makeText(MainActivity.this, "Clicked: " + menuItem.getTitle(), Toast.LENGTH_SHORT).show();
// Closing drawer on item click
mDrawerLayout.closeDrawers();
return true;
}
});
// Adding Floating Action Button to bottom right of main view
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Snackbar.make(v, "Hello Snackbar!",
Snackbar.LENGTH_LONG).show();
}
});
// Network request test with volley
NetworkRequests networkRequest = new NetworkRequests(this);
networkRequest.fetchDummyData();
divisionList = networkRequest.getDivisions();
}
// Add Fragments to Tabs
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new ListContentFragment(), "List");
adapter.addFragment(new TileContentFragment(), "Tile");
adapter.addFragment(new CardContentFragment(), "Card");
viewPager.setAdapter(adapter);
}
Fragment (currently its hard coded, want to populate with the ArrayList)
public class ListContentFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RecyclerView recyclerView = (RecyclerView) inflater.inflate(
R.layout.recycler_view, container, false);
ContentAdapter adapter = new ContentAdapter(recyclerView.getContext());
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return recyclerView;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView avator;
public TextView name;
public TextView description;
public ViewHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.item_list, parent, false));
avator = (ImageView) itemView.findViewById(R.id.list_avatar);
name = (TextView) itemView.findViewById(R.id.list_title);
description = (TextView) itemView.findViewById(R.id.list_desc);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, DetailActivity.class);
intent.putExtra(DetailActivity.EXTRA_POSITION, getAdapterPosition());
context.startActivity(intent);
}
});
}
}
/**
* Adapter to display recycler view.
*/
public static class ContentAdapter extends RecyclerView.Adapter<ViewHolder> {
// Set numbers of List in RecyclerView.
private static final int LENGTH = 18;
private final String[] mPlaces;
private final String[] mPlaceDesc;
private final Drawable[] mPlaceAvators;
public ContentAdapter(Context context) {
Resources resources = context.getResources();
mPlaces = resources.getStringArray(R.array.places);
mPlaceDesc = resources.getStringArray(R.array.place_desc);
TypedArray a = resources.obtainTypedArray(R.array.place_avator);
mPlaceAvators = new Drawable[a.length()];
for (int i = 0; i < mPlaceAvators.length; i++) {
mPlaceAvators[i] = a.getDrawable(i);
}
a.recycle();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.avator.setImageDrawable(mPlaceAvators[position % mPlaceAvators.length]);
holder.name.setText(mPlaces[position % mPlaces.length]);
holder.description.setText(mPlaceDesc[position % mPlaceDesc.length]);
}
#Override
public int getItemCount() {
return LENGTH;
}
}
}
If you want to pass an ArrayList to your fragment, then you need to make sure the Model class is implements Parcelable.
Here i can show an example.
public class ObjectName implements Parcelable {
public ObjectName(Parcel in) {
super();
readFromParcel(in);
}
public static final Parcelable.Creator<ObjectName> CREATOR = new Parcelable.Creator<ObjectName>() {
public ObjectName createFromParcel(Parcel in) {
return new ObjectName(in);
}
public ObjectName[] newArray(int size) {
return new ObjectName[size];
}
};
public void readFromParcel(Parcel in) {
Value1 = in.readInt();
Value2 = in.readInt();
Value3 = in.readInt();
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(Value1);
dest.writeInt(Value2);
dest.writeInt(Value3);
}
}
then you can add ArrayList<ObjectName> to a Bundle object.
ArrayList<ObjectName> arraylist = new Arraylist<ObjectName>();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("arraylist", arraylist);
fragment.setArguments(bundle);
After this you can get back this data by using,
Bundle extras = getIntent().getExtras();
ArrayList<ObjectName> arraylist = extras.getParcelableArrayList("arraylist");
At last you can show list with these data in fragment. Hope this will help to get your expected answer.
I was also stuck with the same problem .
You can try this.
Intead of sending the arraylist as bundle to fragment.Make the arraylist to be passed,as public and static in the activity.
public static Arraylist<Division> arraylist;
Then after parsing and adding the data in the arraylist make the call to the fragment.In the fragment you can the use the arraylist as:
ArrayList<Division> list=MainActivity.arraylist;
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.v(TAG, "onCreateView");
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
// setting up the view pager and tab layout
mViewPager = (ViewPager) rootView.findViewById(R.id.view_pager);
mTabLayout = (TabLayout) rootView.findViewById(R.id.tab_layout);
PageAdapter adapter = new PageAdapter(getFragmentManager());
mViewPager.setAdapter(adapter);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
return rootView;
}
My custom pager adapter looks like this:
public class PageAdapter extends FragmentStatePagerAdapter {
public PageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new GroupTabFragment(position);
}
#Override
public CharSequence getPageTitle(int position) {
String title = "";
switch (position) {
case 0:
title = "Game"; // this is from a template, i have to
break; // return title dynamically
case 1:
title = "Movie";
break;
}
return title;
}
#Override
public int getCount() {
return 2; // the tabs number is a subject of change
} // i don't know it from the begining
}
The problem i have is that i have to add or remove a tab when a button is clicked, or something like this.
Each tab will display a classic list of objects.
Thank you.
There are 2 ways doing this although ViewPager is not suitable for dynamic removing:
1) Pass ArrayList<Fragment> data as parameter to PageAdapter
Then Adapter will look like this:
public class PageAdapter extends FragmentStatePagerAdapter {
private ArrayList<Fragment> data;
public PageAdapter(FragmentManager fm, ArrayList<Fragment> data) {
super(fm);
this.data = data;
}
#Override
public Fragment getItem(int position) {
return data.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
String title = "";
switch (position) {
case 0:
title = "Game"; // this is from a template, i have to
break; // return title dynamically
case 1:
title = "Movie";
break;
}
return title;
}
#Override
public int getCount() {
return data.size(); // the tabs number is a subject of change
} // i don't know it from the begining
}
to remove item you do in Activity\Fragment:
data.remove(fragmentId);
adapter.notifyDataSetChanged();
2) Recreate adapter every time you want to delete item. So you basically create new adapter with new data.
data.remove(fragmentId);
PageAdapter adapter = new PageAdapter(getFragmentManager(), data);
mViewPager.setAdapter(adapter);
Instead of using mTabLayout.setupWithViewPager(mViewPager); you can setup your tabs manually:
mTabLayout.addTab(mTabLayout.newTab().setText("Movie"));
mTabLayout.addTab(mTabLayout.newTab().setText("Game"));
mTabLayout.addTab(mTabLayout.newTab().setText("Audio"));
mTabLayout.setOnTabSelectedListener(this);
Removing is also easy: removeTabAt(int position) or removeTab(Tab tab)
Here I have found some better solution to remove all the views / fragments from the current context.
Here I have used TabLayout and ViewPage within Fragment.
So we need to clear tabs from TabLayout, views from ViewPage and fragments from FragmentManager.
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
FragmentManager fragmentManager = null;
public TabLayout tabLayout;
public ViewPager viewPager;
public ViewPagerAdapter(FragmentManager manager, TabLayout tabLayout, ViewPager pager) {
super(manager);
this.fragmentManager= manager;
this.tabLayout = tabLayout;
this.viewPager= pager;
}
public void removeAll() {
tabLayout.removeAllTabs();
viewPager.removeAllViewsInLayout();
viewPager.removeAllViews();
viewPager.setAdapter(null);
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
if (manager.getFragments() != null) {
manager.getFragments().clear();
}
viewPager.setAdapter(adapterPage);
viewPager.invalidate();
viewPager.requestLayout();
mFragmentList.clear();
mFragmentTitleList.clear();
}
I have a main activity with a View Pager and a Spinner. When I change the spinner, i want the fragments in the ViewPager to update to use new data.
I have tried to communicate from the Activity to the Fragment when a selection has been made in the Spinner but I keep getting a NullPointerException.
i call the updateListView() method from the Activity whenever the Spinner selection has been confirmed. The commented line of code also causes it to crash.
ListFragment lf = (ListFragment) mSectionsPagerAdapter.getItem(0);
lf.updateListView();
Here is my code
public class ListFragment extends Fragment {
ArrayList<Psalm> psalms;
ListViewAdapter adapter;
View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
v = inflater.inflate(R.layout.fragment_list, parent, false);
psalms = GlobalSingleton.get(getActivity()).getPsalms().getPsalms();
adapter = new ListViewAdapter(getActivity(), psalms);
ListView l = (ListView) v.findViewById(R.id.fragmentListListView);
l.setAdapter(adapter);
return v;
}
public void updateListView(){
psalms = GlobalSingleton.get(getActivity()).getPsalms().getPsalms();
System.out.println("HERE");
((ListViewAdapter) ((ListView) v.findViewById(R.id.fragmentListListView)).getAdapter()).notifyDataSetChanged();
//adapter.notifyDataSetChanged();
}
}
main activity
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
String[] files = getAssets().list("");
ArrayList<Psalm> singPsalms = new ArrayList<Psalm>();
ArrayList<Psalm> scottishPsalter = new ArrayList<Psalm>();
for(String s: files){
if(s.split("_")[0].equals("SingPsalms")){
singPsalms.add(new Psalm(s.split("_")[1], s.split("_")[2], s.split("_")[3].replace(".txt", "")));
} else if(s.split("_")[0].equals("ScottishPsalter")){
scottishPsalter.add(new Psalm(s.split("_")[1] , s.split("_")[2], s.split("_")[3].replace(".txt", "")));
}
}
Collections.sort(singPsalms, new PsalmComparator());
GlobalSingleton.get(this).setSingPsalms(new Psalmody("Sing Psalms", singPsalms));
GlobalSingleton.get(this).setScottishPsalter(new Psalmody("Scottish Psalter", scottishPsalter));
GlobalSingleton.get(this).setSelectedPsalmody("Scottish Psalter");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Adapter
Spinner psalter = (Spinner) findViewById(R.id.spinner1);
SpinnerAdapter adapter = ArrayAdapter.createFromResource(this, R.array.psalter, android.R.layout.simple_spinner_dropdown_item);
psalter.setAdapter(adapter);
psalter.setOnItemSelectedListener( new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selected = parent.getItemAtPosition(position).toString();
if (!selected.equals(GlobalSingleton.get(getApplicationContext()).getSelectedPsalmody())){
GlobalSingleton.get(getApplicationContext()).setSelectedPsalmody(selected);
System.out.println("HERE");
ListFragment lf = (ListFragment) mSectionsPagerAdapter.getItem(0);
lf.updateListView();
}
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = null;
if (position == 0){
fragment = new ListFragment();
} else {
fragment = new GridFragment();
}
return fragment;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "List".toUpperCase(l);
case 1:
return "Grid".toUpperCase(l);
case 2:
return "Metre Seperated".toUpperCase(l);
}
return null;
}
}
}
Use same object of ListView on which you are calling setAdapter in onCreateView for calling notifyDataSetChanged as:
....
l = (ListView) v.findViewById(R.id.fragmentListListView);
l.setAdapter(adapter);
return v;
}
ListView l;
public void updateListView(){
//....
l.getAdapter()).notifyDataSetChanged();
//adapter.notifyDataSetChanged();
}
try below code. do not use view and use member listview.
public class ListFragment extends Fragment {
ArrayList<Psalm> psalms;
ListViewAdapter adapter;
ListView l;
View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
v = inflater.inflate(R.layout.fragment_list, parent, false);
psalms = GlobalSingleton.get(getActivity()).getPsalms().getPsalms();
adapter = new ListViewAdapter(getActivity(), psalms);
l = (ListView) v.findViewById(R.id.fragmentListListView);
l.setAdapter(adapter);
return v;
}
public void updateListView(){
psalms = GlobalSingleton.get(getActivity()).getPsalms().getPsalms();
System.out.println("HERE");
if(l != null){
l.getAdapter()).notifyDataSetChanged();
}
}