I want to display Fragments in a ViewPager however it is only showing the first Fragment in the view tabs. The only fragment that gets shown is the one returned at postion 0 in the getItem(0 method - this fragment is displayed in subsequent views.
FragmentPagerAdapter:
public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {
public SimpleFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return new WorldFragment();
} else if (position == 1) {
return new PoliticsFragment();
} else if (position == 2) {
return new TechnologyFragment();
} else if (position == 3) {
return new ScienceFragment();
} else if (position == 4) {
return new SportsFragment();
} else if (position == 5) {
return new FoodFragment();
} else if (position == 6) {
return new TravelFragment();
} else if (position == 7) {
return new MoviesFragment();
} else if (position == 8) {
return new FashionFragment();
} else {
return new OpinionFragment();
}
}
#Override
public int getCount() {
return 10;
}
}
Fragment:
public class WorldFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<Story>> {
public static final String LOG_TAG = WorldFragment.class.getName();
private static final String NY_TIMES_REQUEST_URL = "https://api.nytimes.com/svc/topstories/v2/world.json?api-key=<API KEY REMOVED>;
private StoryAdapter mAdapter;
private TextView mEmptyTextView;
private View rootView;
public WorldFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.story_list, container, false);
mAdapter = new StoryAdapter(getActivity(), new ArrayList<Story>());
final ListView listView = (ListView) rootView.findViewById(R.id.story_list);
mEmptyTextView = (TextView) rootView.findViewById(R.id.empty_textview);
listView.setEmptyView(mEmptyTextView);
listView.setAdapter(mAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Story currentStory = mAdapter.getItem(position);
String url = currentStory.getmURL();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
});
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
if (isConnected) {
LoaderManager loaderManager = getActivity().getLoaderManager();
loaderManager.initLoader(0, null, this);
} else {
View loadingIndicator = rootView.findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
mEmptyTextView = (TextView) rootView.findViewById(R.id.empty_textview);
mEmptyTextView.setText(R.string.no_internet_connection);
}
return rootView;
}
#Override
public android.content.Loader<List<Story>> onCreateLoader(int i, Bundle bundle) {
return new StoryLoader(getActivity(), NY_TIMES_REQUEST_URL);
}
#Override
public void onLoadFinished(android.content.Loader<List<Story>> loader, List<Story> stories) {
mAdapter.clear();
View loadingIndicator = rootView.findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
mEmptyTextView.setText(R.string.no_new_stories);
if (stories != null && !stories.isEmpty()) {
mAdapter.addAll(stories);
}
}
#Override
public void onLoaderReset(android.content.Loader<List<Story>> loader) {
mAdapter.clear();
}
#Override
public void onStop() {
super.onStop();
}
}
ViewPager XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.topworldstories.MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
List XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent">
<ListView
android:id="#+id/story_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="true" />
<TextView
android:id="#+id/empty_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
tools:text="No new stories"/>
<ProgressBar
android:id="#+id/loading_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_centerInParent="true"/>
</LinearLayout>
I am unsure of what is causing this. Any help is appreciated
it is only showing the first Fragment multiple times in the view tabs
Two possibilities I see, both of which are copy-paste errors.
1) You didn't change this URL (notice world.json)
private static final String NY_TIMES_REQUEST_URL = "https://api.nytimes.com/svc/topstories/v2/world.json?api-key=<API KEY REMOVED>";
2) You didn't use a different layout.
rootView = inflater.inflate(R.layout.story_list, container, false);
But since your data seems to be consistent, I'm guessing #1 is true.
If you have 10 different URL's that you want to display in the same "fragment layout", you do not need 10 separate Fragment files.
For example, one Fragment
public class NyTimesFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<Story>> {
public static final String LOG_TAG = NyTimesFragment.class.getName();
private static final String NY_TIMES_URL = "nyTimesURL";
private StoryAdapter mAdapter;
private TextView mEmptyTextView;
private View rootView;
public NyTimesFragment(String url) {
Bundle b = new Bundle();
b.putExtra(NY_TIMES_URL, url); // Pass URL here
setArguments(b);
}
public NyTimesFragment() {
// Required empty public constructor
}
#Override
public android.content.Loader<List<Story>> onCreateLoader(int i, Bundle bundle) {
// Load url here
String url = getArguments().getString(NY_TIMES_URL);
return new StoryLoader(getActivity(), url);
}
That you pass any NyTimes URL to
public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {
// List of NyTimes topics
private String[] topics = { "world", "politics" };
// !!! Do NOT store this in your app... !!!
private static final String API_KEY = "XXXXX";
public SimpleFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
private String getURL(String apiKey, String topic) {
return String.format(
"https://api.nytimes.com/svc/topstories/v2/%s.json?api-key=%s",
topic, apiKey);
}
#Override
public int getCount() {
return topics.length; // Assuming each fragment goes to NyTimes
}
#Override
public Fragment getItem(int position) {
final String url = getURL(topics[position], API_KEY);
// Call the other constructor
return new NyTimesFragment(url);
} // done... no if statements.
Something to consider to make this somewhat better would be Retrofit + Gson...
Ok so the issue here is I was using the same loader id in initloader for each fragment & this is why the same data was being loaded. The loader id needs to be unique for each fragment for this to work.
Related
I'm currently developing an App where I want to use a bottom Navigation with multiple dynamically created Fragments.
Therefore I set up a test app to get used to these funtions.
The problem is now, if I create the ListFragment by a static XML the ListView is created correctly, but If I create it dynamically the ListView does not get displayed, only the BottomNavigation is displayed, nothing else.
Main Activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addFragment();
}
private void addFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyListFragment myListFragment = new MyListFragment();
fragmentTransaction.add(R.id.fragmentContainer, myListFragment);
fragmentTransaction.commit();
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragmentContainer"
android:layout_margin="5dp"
android:layout_alignTop="#+id/bottom_nav"/>
<android.support.design.widget.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="48dp"
android:id="#+id/bottom_nav"
app:menu="#menu/menu_bottom_nav"
android:background="#808080"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
ListFragment:
public class MyListFragment extends ListFragment implements AdapterView.OnItemClickListener {
CustomerAdapter customerAdapter;
ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Customer customer = new Customer("Testcustomer","123456", "654321");
customerAdapter = new CustomerAdapter(Objects.requireNonNull(getActivity()),R.layout.list_pack_item);
listView = new ListView(getActivity());
listView.setAdapter(customerAdapter);
customerAdapter.add(customer);
listView.setOnItemClickListener(this);
return listView;
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//do stuff
}
}
CustomerAdapter:
public class CustomerAdapter extends ArrayAdapter {
List list = new ArrayList();
public CustomerAdapter(#NonNull Context context, int resource ) {
super(context, resource);
}
public void add( #Nullable Customer object ) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return list.size();
}
#Nullable
#Override
public Object getItem(int position ) {
return list.get(position);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent ) {
View row;
row = convertView;
CustomerHolder customerHolder;
if (row == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.list_pack_item, parent, false);
customerHolder = new CustomerHolder();
customerHolder.tx_name = row.findViewById(R.id.tx_name);
customerHolder.tx_intern = row.findViewById(R.id.tx_intern);
customerHolder.tx_extern = row.findViewById(R.id.tx_extern);
row.setTag(customerHolder);
} else {
customerHolder = (CustomerHolder) row.getTag();
}
Customer customer = (Customer) this.getItem(position);
customerHolder.tx_name.setText(customer.getName());
customerHolder.tx_intern.setText("Internal Number: " + customer.getMyCustomerNumber());
customerHolder.tx_extern.setText("Supplier Number: " + customer.getSupplierNumber());
return row;
}
static class CustomerHolder {
TextView tx_name, tx_intern, tx_extern;
}
}
Customer Class
public class Customer {
private String name;
private String supplierNumber;
private String myCustomerNumber;
public Customer(String name, String supplierNumber, String myCustomerNumber) {
this.name = name;
this.supplierNumber = supplierNumber;
this.myCustomerNumber = myCustomerNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSupplierNumber() {
return supplierNumber;
}
public void setSupplierNumber(String supplierNumber) {
this.supplierNumber = supplierNumber;
}
public String getMyCustomerNumber() {
return myCustomerNumber;
}
public void setMyCustomerNumber(String myCustomerNumber) {
this.myCustomerNumber = myCustomerNumber;
}
}
If there is any further information or code needed please let me know!
Additionally: I need to create the fragments dynamically in order to replace them, am I correct?
I have a tablayout, from android design support library:
compile 'com.android.support:design:23.0.1'
With this, I want to populate my tabs. But I'm failing to do that. I can create the tabs, but they fail to inflate their respective content:
Where it should have entries from LinearListView, an object similar to a ListView imported from this framework:
compile 'com.github.frankiesardo:linearlistview:1.0.1#aar'
I tried a great number of examples, but I failed to populate each tab. Any suggestions?
Code:
JAVA:
From main fragment:
OverviewTabLayoutPagerAdapter adapter = new OverviewTabLayoutPagerAdapter(getActivity().getSupportFragmentManager(), productDataContent, getContext());
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager);
OverviewTabLayoutPagerAdapter:
public class OverviewTabLayoutPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
private String tabTitles[] = new String[] { "REVIEWS", "VIDEOS", "DEALS" };
private SearchContent productDataContent;
private Context context;
public OverviewTabLayoutPagerAdapter(FragmentManager fm, SearchContent productDataContent, Context context) {
super(fm);
this.productDataContent = productDataContent;
this.context = context;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
Log.i("TAB_POSITION", String.valueOf(position));
if (position == 0) {
return OverviewTab1Fragment.newInstance(position, productDataContent);
} else if (position == 1) {
return OverviewTab2Fragment.newInstance(position, productDataContent);
} else if (position == 2) {
return OverviewTab3Fragment.newInstance(position, productDataContent);
}
return OverviewTab1Fragment.newInstance(position, productDataContent);
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
OverviewTab*Fragment: (the * means the same code structure applies for every fragment):
public class OverviewTab*Fragment extends Fragment {
public static final String ARG_PAGE = "ARG_PAGE";
public static final String PRODUCT_DATA_CONTENT = "PRODUCT_DATA_CONTENT";
private int mPage;
private SearchContent productDataContent;
public static OverviewTab*Fragment newInstance(int page, SearchContent productDataContent) {
OverviewTab*Fragment fragment = new OverviewTab*Fragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
args.putSerializable(PRODUCT_DATA_CONTENT, productDataContent);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments().getInt(ARG_PAGE);
productDataContent = (SearchContent) getArguments().getSerializable(PRODUCT_DATA_CONTENT);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_tab_fragment, container, false);
LinearListView tabContentListView = (LinearListView) view.findViewById(R.id.product_content_linear_list_view);
populateOverviewTab*LinearLayout(tabContentListView, productDataContent);
return view;
}
private void populateOverviewTab*LinearLayout(LinearListView tabContentListView, SearchContent productDataContent) {
ArrayList<> productData = productDataContent.getContent();
OverviewTab*ArrayAdapter overviewTab*ArrayAdapter = new OverviewVideosArrayAdapter(
getContext(),
tabContentListView,
productData,
getActivity()
);
tabContentListView.setAdapter(overviewTab*ArrayAdapter);
...
XML:
From main fragment:
...
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/go_to_store_button"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
...
overview_tab_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.linearlistview.LinearListView
android:id="#+id/product_content_linear_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:showDividers="end"
android:dividerPadding="5dp"
app:dividerThickness="2dp">
</com.linearlistview.LinearListView>
</RelativeLayout>
You can change:
#Override
public Fragment getItem(int position) {
Log.i("TAB_POSITION", String.valueOf(position));
if (position == 0) {
return OverviewTab1Fragment.newInstance(position, productDataContent);
} else if (position == 1) {
return OverviewTab2Fragment.newInstance(position, productDataContent);
} else if (position == 2) {
return OverviewTab3Fragment.newInstance(position, productDataContent);
}
return OverviewTab1Fragment.newInstance(position, productDataContent);
}
for this:
#Override
public Fragment getItem(int position) {
Log.i("TAB_POSITION", String.valueOf(position));
if (position == 0) {
return OverviewTab1Fragment.instantiate(context, productDataContent);
} else if (position == 1) {
return OverviewTab2Fragment.instantiate(context, productDataContent);
} else if (position == 2) {
return OverviewTab3Fragment.instantiate(context, productDataContent);
}
return OverviewTab1Fragment.instantiate(context, productDataContent);
}
UPDATE
This is an example with Fragment in Array:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.util.SparseArray;
import android.view.ViewGroup;
public class TabsViewPagerAdapter extends FragmentStatePagerAdapter {
private CharSequence titlesArray[]; // This will Store the Titles of the Tabs which are Going to be passed when TabsViewPagerAdapter is created
private Fragment tabsArray[];
private SparseArray<Fragment> registeredFragments;
// Build a Constructor and assign the passed Values to appropriate values in the class
public TabsViewPagerAdapter(FragmentManager fm, CharSequence titlesArray[], Fragment[] tabsArray) {
super(fm);
this.titlesArray = titlesArray;
this.tabsArray = tabsArray;
this.registeredFragments = new SparseArray<>();
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
return tabsArray[position];
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return titlesArray[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return titlesArray.length;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
In the Java you create the adapter:
String[] tabTitles = new String[]{"Tab1", "Tab2", "Tab3"};
Fragment[] tabsArray = new Fragment[]{new OverviewTab1Fragment(), new OverviewTab2Fragment(), new OverviewTab3Fragment()};
adapter = new TabsViewPagerAdapter(getSupportFragmentManager(), tabTitles, tabsArray);
And the fragment is something like this:
import android.support.v4.app.Fragment;
public class OverviewTab1Fragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.yourFragmentLayout, container, false);
return v;
}
}
I hope help you.
I have ViewPager that containing 3 different Fragment. each Fragment containing A Different View and also ListView, I got a problem when I was trying to show the ListView in one of Fragment from ViewPager, it doesn't show anything. I've tried to debug my adapter and it seems my getView() method is not called. I try to call my Fragment not from ViewPager, the result is getView() is called from adapter and ListView is showing. Is there any problem to show ListView from ViewPager? I have tried this solution by calling my adapter from onViewCreated() but there's nothing change. so is there any wrong with my method? this is my code :
My Fragment Class for Managing ViewPager
public class Frag_Provider extends Fragment {
private String[] tabsTitles = {"TERDEKAT", "SEMUA", "PROVIDERKU"};
String url = "";
List<ModelProvider> list_provider;
DB_Esehat db_esehat = null;
SQLiteDatabase db = null;
ContentLoadingProgressBar progressbar;
TabLayout tabLayout;
ViewPager pager;
public Frag_Provider (){
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
((MainActivity) getActivity()).custom_toolbar("Provider", R.color.toolbar_provider, R.color.toolbar_provider_dark);
View result=inflater.inflate(R.layout.fragment_provider, container, false);
list_provider = new ArrayList<ModelProvider>();
progressbar = (ContentLoadingProgressBar)result.findViewById(R.id.progressbar);
db_esehat = new DB_Esehat(getActivity());
db = db_esehat.getWritableDatabase();
db.delete("LST_PROVIDER", null, null);
pager=(ViewPager)result.findViewById(R.id.pager);
tabLayout = (TabLayout)result.findViewById(R.id.sliding_tabs);
url = getResources().getString(R.string.url_host)+getResources().getString(R.string.url_provider);
new ProviderTask(url).execute();
pager.setAdapter(buildAdapter(tabsTitles));
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(pager);
}
});
return(result);
}
public class ProviderTask extends AsyncTask<String, Void, String> {
String url = "";
public ProviderTask(String url) {
this.url = url;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressbar.setVisibility(View.VISIBLE);
}
#Override
protected String doInBackground(String... params) {
String result = "";
try {
result = Connection.get(url);
} catch (Exception e) {
result = "";
}
return result;
}
#Override
protected void onPostExecute(String result) {
progressbar.setVisibility(View.GONE);
pager.setVisibility(View.VISIBLE);
tabLayout.setVisibility(View.VISIBLE);
super.onPostExecute(result);
if (result.equals("") || result.equals(null)) {
MethodSupport.AlertDialog(getActivity());
} else {
try {
JSONArray Data = new JSONArray(result);
for (int i = 0; i < Data.length(); i++) {
String LSKA_NOTE = "";
String RSALAMAT = "";
String RSTELEPON = "";
String RSNAMA = "";
String MAPPOS = "";
int RSTYPE = 0;
int RSID = 0;
int RS_NTT = 0;
JSONObject json = Data.getJSONObject(i);
if (json.has("LSKA_NOTE")) {
LSKA_NOTE = json.getString("LSKA_NOTE");
}
if (json.has("RSALAMAT")) {
RSALAMAT = json.getString("RSALAMAT");
}
if (json.has("RSTELEPON")) {
RSTELEPON = json.getString("RSTELEPON");
}
if (json.has("RSNAMA")) {
RSNAMA = json.getString("RSNAMA");
}
if (json.has("MAPPOS")) {
MAPPOS = json.getString("MAPPOS");
}
if (json.has("RSTYPE")) {
RSTYPE = json.getInt("RSTYPE");
}
if (json.has("RSID")) {
RSID = json.getInt("RSID");
}
if (json.has("RS_NTT")) {
RS_NTT = json.getInt("RS_NTT");
}
db_esehat.InsertRS(LSKA_NOTE, RSALAMAT, RSTELEPON, RSNAMA, MAPPOS, RSTYPE, RSID, RS_NTT);
}
} catch (Exception e) {
Log.d("TES", e.getMessage());
}
}
}
}
private PagerAdapter buildAdapter(String[] tabsTitles) {
return(new FragmentStatePagerAdapter(getActivity(), getChildFragmentManager(),tabsTitles));
}
}
This is FragmentStatePagerAdapter.java
public class FragmentStatePagerAdapter extends FragmentPagerAdapter {
Context ctxt=null;
private String[] tabsTitles;
public FragmentStatePagerAdapter(Context ctxt, FragmentManager mgr, String[] tabsTitles) {
super(mgr);
this.ctxt=ctxt;
this.tabsTitles = tabsTitles;
}
#Override
public int getCount() {
return tabsTitles.length;
}
#Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return Frag_Provider_Terdekat.newInstance(position);
case 1:
return Frag_Provider_Semua.newInstance(position);
case 2:
return Frag_Provider_Ku.newInstance(position);
}
return null;
}
// #Override public float getPageWidth(int position) { return(0.7f); }
#Override
public String getPageTitle(int position) {
return tabsTitles[position];
}
}
this is my Fragment_Provider.xml, Layout for managing my ViewPager
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.ContentLoadingProgressBar
android:id="#+id/progressbar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
android:indeterminate="false" />
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
style="#style/MyCustomTabLayout"
app:tabMode="fixed"
android:fillViewport="true"
android:visibility="gone" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white"
android:layout_below="#id/sliding_tabs"
android:visibility="gone"/>
</RelativeLayout>
This is of my Fragment in ViewPagerthat containing ListView :
public class Frag_Provider_Terdekat extends Fragment {
private static final String KEY_POSITION="position";
private ListView list_provider;
List<ModelProviderTerdekat> list_ekamedicare;
DB_Esehat db_esehat;
SQLiteDatabase db;
ProviderTerdekatAdapter adapter;
static Frag_Provider_Terdekat newInstance(int position) {
Frag_Provider_Terdekat frag=new Frag_Provider_Terdekat();
Bundle args=new Bundle();
args.putInt(KEY_POSITION, position);
frag.setArguments(args);
return(frag);
}
static String getTitle(Context ctxt, int position) {
return("PROVIDER KU");
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View result=inflater.inflate(R.layout.fragment_child_providerterdekat, container, false);
list_provider = (ListView)result.findViewById(R.id.list_provider);
list_ekamedicare = new ArrayList<ModelProviderTerdekat>();
db_esehat = new DB_Esehat(getActivity());
list_ekamedicare = db_esehat.getProvider();
adapter = new ProviderTerdekatAdapter(getActivity().getApplicationContext(), R.layout.adapter_provider, list_ekamedicare);
list_provider.setAdapter(adapter);
return result;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
and this is Adapter for my ListView
public class ProviderTerdekatAdapter extends ArrayAdapter<ModelProviderTerdekat> {
List<ModelProviderTerdekat> data = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
static class ViewHolder {
ImageView imvprov_map;
ImageView imvprov_fav;
TextView textprov_nama_rs;
TextView textprov_alamat_rs;
TextView textprov_km_rs;
}
public ProviderTerdekatAdapter (Context context, int viewResourceId, List<ModelProviderTerdekat> data) {
super(context, R.layout.adapter_provider, data);
this.context = context;
inflater = LayoutInflater.from(context);
this.data = data;
}
#Override
public int getCount() {
return data.size();
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = inflater.inflate(R.layout.adapter_provider, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.imvprov_map = (ImageView) view.findViewById(R.id.imvprov_map);
viewHolder.imvprov_fav = (ImageView) view.findViewById(R.id.imvprov_fav);
viewHolder.textprov_nama_rs = (TextView) view.findViewById(R.id.textprov_nama_rs);
viewHolder.textprov_alamat_rs = (TextView) view.findViewById(R.id.textprov_alamat_rs);
viewHolder.textprov_km_rs = (TextView) view.findViewById(R.id.textprov_km_rs);
view.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) view.getTag();
viewHolder.textprov_nama_rs.setText(data.get(position).getRSNAMA());
viewHolder.textprov_alamat_rs.setText(data.get(position).getRSALAMAT());
return view;
}
}
I have no Idea why my GetView() not called in my Adapter, is it because I put in ViewPager? well I hope someone understand about it and help me to solver my problem. thank you very much.
Finally.. I found a solution for my problem, it's because I put ViewPager in RelativeLayout after I change into LinearLayout all view displayed as I wanted
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.ContentLoadingProgressBar
android:id="#+id/progressbar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
android:indeterminate="false" />
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
style="#style/MyCustomTabLayout"
app:tabMode="fixed"
android:fillViewport="true"
android:visibility="gone" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white"
android:layout_below="#id/sliding_tabs"
android:visibility="gone"/>
</LinearLayout>
I'm trying to get this working: I basically want two Recyclerviews in one ViewPager. I followed this Tutorial: http://android-java-development.blogspot.de/2012/05/system.html, but it doesn't seem to work. I looks like the view pager is empty and the recycler view doesn't show up.
Here's my layout code:
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/pager_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="#dimen/tab_height">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/accent"/>
</android.support.v4.widget.SwipeRefreshLayout>
And my PageAdapter:
public class NewsPagerAdapter extends PagerAdapter {
private Context context;
private Vector<RecyclerView> recyclerViewList;
private String[] titles;
public NewsPagerAdapter(Context context, int titlesId) {
this.context = context;
this.recyclerViewList = new Vector<>();
setTitles(titlesId);
}
public void add(RecyclerView recyclerView) {
recyclerViewList.add(recyclerView);
}
public RecyclerView.Adapter getAdapterForViewAtIndex(int index) {
return recyclerViewList.get(index).getAdapter();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(recyclerViewList.get(position),
new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 100)
);
return container;
}
#Override
public int getCount() {
return recyclerViewList.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
public void setTitles(int titles) {
this.titles = context.getResources().getStringArray(titles);
}
}
And my onCreatView method:
GridLayoutManager layoutManager1 = new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.news_column_count));
GridLayoutManager layoutManager2 = new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.news_column_count));
RecyclerView listView1 = new RecyclerView(getActivity());
RecyclerView listView2 = new RecyclerView(getActivity());
listView1.setLayoutManager(layoutManager1);
listView2.setLayoutManager(layoutManager2);
NewsAdapter adapter1 = new NewsAdapter(getActivity(), null);
NewsAdapter adapter2 = new NewsAdapter(getActivity(), null);
adapter1.setOnItemClickListener(this);
adapter2.setOnItemClickListener(this);
listView1.setAdapter(adapter1);
listView2.setAdapter(adapter2);
newsPagerAdapter.add(listView1);
newsPagerAdapter.add(listView2);
newsViewPager.setAdapter(newsPagerAdapter);
Here I'm passing the cursor object to the adapter:
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
((NewsAdapter) newsPagerAdapter.getAdapterForViewAtIndex(0)).swapCursor(data);
}
You have to extend FragmentPagerAdapter or FragmentStatePagerAdapter in order to easily embed RecyclerView. If you are going to update your ViewPager contents during its lifecycle it is strictly recommended to use FragmentStatePagerAdapter
You will have to create additional fragment layout, containing RecyclerView.
If you wish to update your ViewPager with SwipeRefreshLayout, don't wrap it with SwipeRefreshLayout. Instead, you must have SwipeRefreshLayout inside fragment layout.
Therefore for your fragment you may get the following xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/categoryList"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
And create additional Fragment class, which will inflate that layout and implement methods, that you will need to update refresh indicator status.
A bit old example is found here:
http://developer.android.com/training/implementing-navigation/lateral.html
If you wish to connect your ViewPager with new support library TabLayout, it is easily one with:
tabLayout.setupWithViewPager(viewPager);
Finally, if you will update your "fragmented" ViewPager, don't try to reset the adapter, as fragments are managed not with adapter, but with FragmentManager. It is wiser to update content of corresponding RecyclerViews
public class MyFragmentedPagerAdapter extends FragmentStatePagerAdapter {
private final TabLayout mTabLayout;
private final SwipeRefreshLayout.OnRefreshListener mRefreshListener;
private Vector<PriceListFragment> fragmentList;
private Vector<String> titles;
public MyFragmentedPagerAdapter(FragmentManager fm, MyComplexData data, OnCartActionListener listener, TabLayout tabLayout, SwipeRefreshLayout.OnRefreshListener refreshListener) {
super(fm);
mTabLayout = tabLayout;
// external refresh listener, that will trigger an updateData()
mRefreshListener = refreshListener;
fragmentList = new Vector<>();
titles = new Vector<>();
updateData(data);
}
public void updateData(MyComplexData data) {
boolean updateTabs = false;
boolean hasNewData = false;
Vector<String> newTitles = new Vector<>();
int position = 0;
for(TabContents tabContents : data.getTabContents()) {
if(tabContents.getListContents() == null)
continue;
hasNewData = true;
boolean isNewFragment;
MyFragment fragment;
try {
fragment = fragmentList.get(position);
isNewFragment = false;
} catch (ArrayIndexOutOfBoundsException e) {
fragment = new MyFragment();
isNewFragment = true;
}
// Update the data, title and hide update indicator of SwipeRefreshLayout
fragment.setTabContents(tabContents);
newTitles.add(tabContents.getName());
if(isNewFragment) {
fragment.setRefreshListener(mRefreshListener);
fragmentList.add(fragment);
}
position++;
}
if(!hasNewData)
return;
// we need to decide, whether to update tabs
if(titles.size() != newTitles.size()) {
updateTabs = true;
} else {
for(position = 0; position < titles.size(); position++) {
if(!titles.get(position).equals(newTitles.get(position))) {
updateTabs = true;
break;
}
}
}
titles = newTitles;
notifyDataSetChanged();
if(updateTabs)
mTabLayout.setTabsFromPagerAdapter(this);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
// You need to override this method as well
#Override
public int getItemPosition(Object object) {
MyFragment fragment = (MyFragment) object;
String title = (String) fragment.getTitle();
int position = titles.indexOf(title);
if (position >= 0) {
return position;
} else {
return POSITION_NONE;
}
}
#Override
public int getCount() {
return titles.size();
}
#Override
public CharSequence getPageTitle(int position) {
return fragmentList.get(position).getTitle();
}
}
Your MyFragment class has to implement getTitle() method.
So I've just been messing around with android for a little bit and I've run into a bit of a snag. The fragment where I am instantiating ListOfJokesTypesAdapter for some reason is not displaying a listview populated with the Data from my JokeData class.
All that I get is a blank screen (no errors or anything of that nature).
This is just a proof of concept thing I've been working on so any help would be greatly appreciated. Why is it that this particular custom adapter is not working while my MainClassAdapter is working just fine.
The Code
My Joke Class:
public class Joke {
private String jokeSetup;
private String jokePunchline;
public Joke(String jokeSetup, String jokePunchline) {
this.jokeSetup = jokeSetup;
this.jokePunchline = jokePunchline;
}
public String getJokeSetup() {
return jokeSetup;
}
public void setJokeSetup(String jokeSetup) {
this.jokeSetup = jokeSetup;
}
public String getJokePunchline() {
return jokePunchline;
}
public void setJokePunchline(String jokePunchline) {
this.jokePunchline = jokePunchline;
}
}
My JokeListClass
public class JokeListData {
private String listName;
private List<Joke> arrayListOfJokes;
public JokeListData(String listName, List<Joke> arrayListOfJokes) {
this.listName = listName;
this.arrayListOfJokes = arrayListOfJokes;
}
public String getListName() {
return listName;
}
public void setListName(String listName) {
this.listName = listName;
}
public List<Joke> getArrayListOfJokes() {
return arrayListOfJokes;
}
public void setArrayListOfJokes(ArrayList<Joke> arrayListOfJokes) {
this.arrayListOfJokes = arrayListOfJokes;
}
}
My Actual Joke Data
public class JokeData {
private static List<Joke> dogJokes = new ArrayList<Joke>(){
{
add(new Joke("Dogs", "Bark"));
add(new Joke("Dogs", "Woof"));
add(new Joke("Dogs", "Howl"));
add(new Joke("Dogs", "Sniff"));
}
};
private static List<Joke> catJokes = new ArrayList<Joke> (){
{
add(new Joke("Cats", "woof"));
add(new Joke("Dogs", "Meow"));
}
};
static List<JokeListData> dataOfJokeList = new ArrayList<JokeListData>();
public static void addEntries(){
dataOfJokeList.add(new JokeListData("Cat Jokes", catJokes));
dataOfJokeList.add(new JokeListData("Dog Jokes", dogJokes));
}
}
The Adapter
public class ListOfJokeTypesAdapter extends ArrayAdapter<JokeListData> {
Context mContext;
int mLayoutId;
List<JokeListData> mList;
public ListOfJokeTypesAdapter(Context context, int resource, List<JokeListData> objects) {
super(context, resource, objects);
this.mContext = context;
this.mLayoutId = resource;
this.mList = objects;
}
#Override
public int getCount() {
return super.getCount();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mLayoutId,parent,false);
holder = new ViewHolder();
holder.mTextView = (TextView) convertView.findViewById(R.id.rowForMainList);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
JokeListData jokeListData = mList.get(position);
holder.mTextView.setText(jokeListData.getListName());
return convertView;
}
private static class ViewHolder{
TextView mTextView;
}
}
The Fragment which utilizes the adapter
public class ListOfJokeTypesFragment extends Fragment {
ListView mListView;
ListOfJokeTypesAdapter listOfJokeTypesAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.joke_type_fragment,container,false);
JokeData.addEntries();
mListView = (ListView)view.findViewById(R.id.jokeTypeListView);
listOfJokeTypesAdapter = new ListOfJokeTypesAdapter(getActivity().getApplicationContext(),R.layout.row,JokeData.dataOfJokeList);
mListView.setAdapter(listOfJokeTypesAdapter);
return view;
}
}
The Fragment Manager
package com.example.taranveer.jokeapplicationactual;
import android.app.Activity;
import android.os.Bundle;
/**
* Created by Taranveer on 2014-07-22.
*/
public class TheFragmentActivityManager extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_container);
Bundle args = getIntent().getExtras();
if(findViewById(R.id.container) != null){
if(args != null){
if(args.getInt("randomjoke") == 1){
RandomJokeFragment randomJokeFragment = new RandomJokeFragment();
getFragmentManager().beginTransaction()
.replace(R.id.container, randomJokeFragment)
.commit();
}
}
}
if(findViewById(R.id.container) != null){
if(args!=null){
if(args.getInt("listofjoketypes") == 2){
ListOfJokeTypesFragment listOfJokeTypesFragment = new ListOfJokeTypesFragment();
getFragmentManager().beginTransaction()
.replace(R.id.container,listOfJokeTypesFragment)
.commit();
}
}
}
}
}
The relevant XML:
joke_type_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/jokeTypeListView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_margin="5dp"
android:gravity="center_vertical"
android:background="#000000"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textColor="#eeeeee"
android:textStyle="bold"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#2299dd"
android:textSize="20sp"
android:text="Main Activity Items"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/rowForMainList"/>
</LinearLayout>
</LinearLayout>
better to put these lines
JokeListData jokeListData = mList.get(position);
holder.mTextView.setText(jokeListData.getListName());
inside if(convertView == null) condition
beforr#Override
public int getCount() {
return super.getCount();
}
remove this line
You need to override getCount() in your custom adapter.
It will return the number of entries in your ListView.
Replace
#Override
public int getCount() {
return super.getCount();
}
With something like
#Override
public int getCount() {
return mySourceArrayList.getCount();
}