The Problem:
In my onCreate() on my main activity, I am trying to set the text value of a TextView in my fragment which is displayed by a viewpager. When I try to get my fragment instance, It always returns null.
Solutions I Tried:
Almost every solution related to this problem on SO gives me the same result(NPE).
My Code is below as well as some explanation...
Home.java Activity (My Main Activity):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Show the home layout
setContentView(R.layout.home);
// Setup the toolbar
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Now setup our tab bar
TabLayout tabLayout = (TabLayout)findViewById(R.id.homeTabs);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
// Setup the view pager
ViewPager viewPager = (ViewPager)findViewById(R.id.viewPager);
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
tabLayout.setupWithViewPager(viewPager);
// Start our service controller
Intent startServiceController = new Intent(this, ServiceController.class);
startService(startServiceController);
Fragment viewFragment = pagerAdapter.getRegisteredFragment(viewPager.getCurrentItem());
if(viewFragment == null){
Log.v("Fragment", "NULL");
}
}
After setting up the pageAdapter and viewpager, I try to access the fragment thats being shown. The code for my PagerAdapter is below...
PagerAdapter:
public class PagerAdapter extends SmartFragmentStatePagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new ParkListFragment();
case 1:
return new MapFragment();
default:
return null;
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
CharSequence title;
switch (position){
case 0:
title = "Spaces Near You";
break;
case 1:
title = "Map";
break;
default:
title = "N/A";
break;
}
return title;
}
}
SmartFragmentStatePagerAdapter:
public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
// Sparse array to keep track of registered fragments in memory
private SparseArray<Fragment> registeredFragments = new SparseArray<>();
public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Register the fragment when the item is instantiated
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
// Unregister when the item is inactive
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
// Returns the fragment for the position (if instantiated)
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
I really don't understand what the issue is. I have tried many things. What I don't want to use is this:
String tag="android:switcher:" + viewId + ":" + index;
ParkListFragment.java:
public class ParkListFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.park_list_fragment, container, false);
}
}
ParkList Fragment Layout:
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/confidenceText"
android:textAlignment="center"
android:textSize="24sp"
android:textColor="#android:color/primary_text_light"
android:padding="10dp"/>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/activityText"
android:textAlignment="center"
android:textSize="24sp"
android:textColor="#android:color/primary_text_light"
android:padding="10dp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
Stack Trace: Pastebin
So after hours of trial and error, the only thing that worked for me was this SO post:
ViewPager Fragments are not initiated in onCreate
Related
Description
I have one activity in the vertical orinentation with two tabs (TabLayout) and fragments, which change with Viewpager.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
// Assign created adapter to viewPager
viewPager.setAdapter(new TabsExamplePagerAdapter(getSupportFragmentManager()));
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// This method setup all required method for TabLayout with Viewpager
tabLayout.setupWithViewPager(viewPager);
}
public class TabsExamplePagerAdapter extends FragmentPagerAdapter {
// As we are implementing two tabs
private static final int NUM_ITEMS = 2;
public TabsExamplePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
// For each tab different fragment is returned
public Fragment getItem(int position) {
switch (position) {
case 0:
return new TabOneFragment();
case 1:
return new TabTwoFragment();
default:
return null;
}
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public CharSequence getPageTitle(int position) {
return "Tab " + (position + 1);
}
}
}
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:tabTextColor="#ffffff"
app:tabIndicatorColor="#fbff3a"
app:tabSelectedTextColor="#fbff3a"
app:tabIndicatorHeight="5dp"
android:elevation="4dp"
app:tabGravity="fill"
app:tabMaxWidth="0dp" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
In each tabs i have for one fragments.
TabOneFragment.java (TabTwoFragment is similar ):
public class TabOneFragment extends Fragment {
// Required empty public constructor
public TabOneFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_one, container, false);
}
}
fragment_one_tab.xml (fragment_one_tab.xml is similar)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="innovatecode.com.tabexample.TabOneFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="18dp"
android:text="#string/tab_one" />
</FrameLayout>
And i have simply result:
My problem
When my device is rotated to the horizontal position, I want to get the following result:
I create xml for horizontal markup (land):
active_main.xml (land)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="#+id/fragment_left"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/fragment_right"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
But I don't know how to change my code to get this result. I'm not very strong in working with fragments.
First, you can improve your landscape layout by adding your fragments directly to the layout file (under "res/layout-land"):
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:name="innovatecode.com.tabexample.TabOneFragment"
android:id="#+id/fragment_left"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment
android:name="innovatecode.com.tabexample.TabTwoFragment"
android:id="#+id/fragment_right"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
You can read move on the topic here.
For the code part, you could make use of distinct features of your landscape and portrait layouts to switch between the corresponding logic in code. For example:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.tab_layout) != null) {
setUpPortraitLayout();
} else {
setUpLandscapeLayout();
}
}
private void setUpPortraitLayout() {
ViewPager viewPager = findViewById(R.id.pager);
// Assign created adapter to viewPager
viewPager.setAdapter(new TabsExamplePagerAdapter(getSupportFragmentManager()));
TabLayout tabLayout = findViewById(R.id.tab_layout);
// This method setup all required method for TabLayout with Viewpager
tabLayout.setupWithViewPager(viewPager);
}
private void setUpLandscapeLayout() {
// Note: with the layout definition suggested above you don't
// need any manual processing to set-up your layout for landscape
// but you still may have some extra set-up (initial binding, etc).
tabOneFragment = (TabOneFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_left);
tabTwoFragment = (TabTwoFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_right);
// ...
}
}
You can pass saved parameters to your fragments via "setArguments()" method. Alternatively consider using "onSaveInstanceState()" methods of your fragments (as opposed to activity, which you use now).
Alternative approach: dynamically add fragments in both landscape and portrait cases. It is based on your code. I think some aspects are arguable (I may be wrong), but changing direction would mean rewriting the whole thing. But it should work eventually.
res/layout-land/active_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="#+id/fragment_left"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/fragment_right"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java (based off the code you shared via gist)
public class MainActivity extends AppCompatActivity {
private Fragment tabOneFragment;
private Fragment tabTwoFragment;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
//Restore the fragment's instance
tabOneFragment = (TabOneFragment) getSupportFragmentManager().getFragment(
savedInstanceState, "tabOneFragment");
tabTwoFragment = (TabTwoFragment) getSupportFragmentManager().getFragment(
savedInstanceState, "tabTwoFragment");
} else {
tabOneFragment = new TabOneFragment();
tabTwoFragment = new TabTwoFragment();
}
if (findViewById(R.id.tab_layout) != null) {
setUpPortraitLayout();
} else {
setUpLandscapeLayout();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "tabOneFragment", tabOneFragment);
getSupportFragmentManager().putFragment(outState, "tabTwoFragment", tabTwoFragment);
}
private void setUpPortraitLayout() {
viewPager = (ViewPager) findViewById(R.id.pager);
// Assign created adapter to viewPager
viewPager.setAdapter(new TabsPagerAdapter(getSupportFragmentManager()));
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// This method setup all required method for TabLayout with Viewpager
tabLayout.setupWithViewPager(viewPager);
}
private void setUpLandscapeLayout() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_left, tabOneFragment);
transaction.replace(R.id.fragment_right, tabTwoFragment);
transaction.addToBackStack(null);
transaction.commit();
}
private class TabsPagerAdapter extends FragmentPagerAdapter {
// As we are implementing two tabs
private static final int NUM_ITEMS = 2;
public TabsPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
// For each tab different fragment is returned
public Fragment getItem(int position) {
switch (position) {
case 0:
return tabOneFragment;
case 1:
return tabTwoFragment;
default:
throw new IllegalStateException("Invalid tab index");
}
}
#Override
public int getCount() { return NUM_ITEMS; }
#Override
public CharSequence getPageTitle(int position) { return "Tab " + (position + 1); }
// NOTE: I think you do not really need to override "instantiateItem()", therefore I removed it.
}
}
I'm making an Android app that uses an appBarLayout with tabs in it and webViews that load an external URL underneath it. In the toolbar menu I want to add a refresh option that refreshes only the current tab. I couldn't figure out how to get it working in my specific case. I already tried this solution but when I press the refresh button, the app crashes.
EDIT: I think the only part I need to edit is if (id == R.id.action_refresh) in my MainActivity.java. But because I have 4 tabs (Tab0, Tab1 etc.) I think it shouldn't say Tab0.webview.reload();, but just the current tab which is open.
Here is my MainActivity.java
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(3);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
//TODO
return true;
}
if (id == R.id.action_refresh) {
//What comes here?
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:
Tab0 tab0 = new Tab0();
return tab0;
case 1:
Tab1 tab1 = new Tab1();
return tab1;
case 2:
Tab2 tab2 = new Tab2();
return tab2;
case 3:
Tab3 tab3 = new Tab3();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
// Show 4 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Tab 0";
case 1:
return "Tab 1";
case 2:
return "Tab 2";
case 3:
return "Tab 3";
}
return null;
}
}
}
My activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.my.app.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
android:background="#android:color/holo_red_light">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#android:color/holo_red_light"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="#android:color/holo_red_light"
app:tabMode="scrollable" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
</android.support.v4.view.ViewPager>
</android.support.design.widget.CoordinatorLayout>
My Tab0.java
public class Tab0 extends Fragment {
WebView webview;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.tab0, container, false);
webview = (WebView)rootView.findViewById(R.id.webview0);
webview.setWebViewClient(new WebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setUseWideViewPort(true);
webview.getSettings().setBuiltInZoomControls(true);
CookieManager.getInstance().setAcceptCookie(true);
webview.loadUrl("https://www.google.com");
return rootView;
}
}
My tab0.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context="com.my.app.MainActivity$SectionsPagerAdapter">
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webview0"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
Can someone help me with implementing the refresh button?
Thanks in advance
The WebView.reload() should be the way to go for you as mentioned in the post you refered.
If your app crash because of it then you probably do soemthing wrong. What is the crash error?
Use following in the onOptionsItemSelected method:
if (id == R.id.action_refresh) {
((WebView) mSectionsPagerAdapter.getItem(0).getView().findViewById(R.id.webview0)).reload();
return true;
}
I'm using TabLayout and ViewPager together to do a tabbed viewpager.
I've got a weird behavior in landscape where TabLayout.GRAVITY_FILL and TabLayout.MODE_FIXED don't seem to work, regardless of being set in java or xml (they do just fine for portrait).
However! When I do THREE tabs, everything is a-ok!
The problem is with TWO tabs - in landscape.
My Activity:
public class TabbedViewPager extends AppCompatActivity {
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed_viewpager);
initTabLayout1();
}
public void initTabLayout1() {
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
TabLayout.Tab tab1 = tabLayout.newTab();
tab1.setText("Tab 1");
tabLayout.addTab(tab1);
TabLayout.Tab tab2 = tabLayout.newTab();
tab2.setText("Tab 2");
tabLayout.addTab(tab2);
//TabLayout.Tab tab3 = tabLayout.newTab();
//tab3.setText("Tab 3");
//tabLayout.addTab(tab3);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
viewPager = (ViewPager) findViewById(R.id.view_pager);
final TabbedPagerAdapter adapter = new TabbedPagerAdapter(getSupportFragmentManager(),
tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {}
#Override
public void onTabReselected(TabLayout.Tab tab) {}
});
}
}
My Fragment, same for both One and Two, (with a blank/bg-colored xml):
public class FragmentOne extends Fragment {
public FragmentOne() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
return view;
}
}
My Adapter:
public class TabbedPagerAdapter extends FragmentStatePagerAdapter {
private int mNumOfTabs;
public TabbedPagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
FragmentOne tab1 = new FragmentOne();
return tab1;
case 1:
FragmentTwo tab2 = new FragmentTwo();
return tab2;
case 2:
FragmentOne tab3 = new FragmentOne();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
My Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_tabbed_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.samp.ling.sampleapp.examples.TabbedViewPager">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:background="#android:color/holo_orange_light"
app:tabIndicatorColor="#android:color/holo_orange_dark"
app:tabIndicatorHeight="5dp"/>
<!--app:tabGravity="fill"-->
<!--app:tabMode="fixed"-->
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
</RelativeLayout>
As seen from above, exact same code besides an extra tab, 2-tabs don't adhere to tablayout's fill/fixed in landscape - why? what's wrong?
Oh, this is with the latest support libraries:
appcompat-v7:25.0.1, support-v4:25.0.1, design:25.0.1
Thanks!
app:tabMaxWidth="0dp" fixed it for landscape
Got the clue from:
https://stackoverflow.com/a/31620690/6668797
just add app:tabMaxWidth="0dp" to layout file
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/main_tablayout"
app:tabGravity="fill"
android:background="#color/colorPrimary"
app:tabIndicatorColor="#color/colorAccent"
app:tabMode="fixed"
app:tabMaxWidth="0dp"
app:tabTextColor="#ffff">
</android.support.design.widget.TabLayout>
I want to add a viewPager for main fragment in my android app.
This is the xml file for main fragment
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
This is the Java code for Main Fragment
public class MainFragment extends ListFragment {
private static final String TAG = MainFragment.class.getSimpleName();
private StudentsDBHandler studentsDBHandler;
public MainFragment() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
studentsDBHandler = new StudentsDBHandler(getActivity());
View rootView = inflater.inflate(R.layout.main_fragment, container, false);
displayStudents();
return rootView;
}
private void displayStudents() {
List<Student> studentList = studentsDBHandler.getAll();
ArrayAdapter<Student> list = new ArrayAdapter<>(getActivity(), R.layout.item_student, studentList);
setListAdapter(list);
}
}
You have a DrawerLayout page. It's about your drawer contains.
İn the DrawerLayout XML
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
add this code below
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
write this code and setup your View pager like example
viewPager=(ViewPager)findViewById(R.id.viewPager);
FragmentManager fm=getSupportFragmentManager();
viewPager.setAdapter(new MyAdapter(fm));
}
class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if(position==0)
fragment= new Home1();
if(position==1)
fragment=new Home2();
return fragment;
}
#Override
public int getCount() {
return 2;
}
}
}
I hope Help you
What I am trying to do is to have a ViewPager section on my app, where the user can scroll to see the results. I am using Android Studio.
At the moment I am currently displaying the results like so, by outputting the values to out by stringing them together:
Part of Main_Activity.java
class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
String tempValue = spinner1.getSelectedItem().toString();
float inputValue;
if(text.getText().length() == 0) {
inputValue = Float.parseFloat("10");
text.setText("10");
}
else {
inputValue = Float.parseFloat(text.getText().toString());
}
if ("Fahrenheit".equals(tempValue)) {
out.setText(String.valueOf(ConverterUtil.convertFahrenheitToCelsius(inputValue)) + " & " + String.valueOf(ConverterUtil.convertFahrenheitToKelvin(inputValue)));
type.setText("Celsius + Kelvin");
}
if ("Celsius".equals(tempValue)) {
out.setText(String.valueOf(ConverterUtil.convertCelsiusToFahrenheit(inputValue)) + " & " + String.valueOf(ConverterUtil.convertCelsiusToKelvin(inputValue)));
type.setText("Fahrenheit + Kelvin");
}
if ("Kelvin".equals(tempValue)) {
out.setText(String.valueOf(ConverterUtil.convertKelvinToCelsius(inputValue)) + " & " + String.valueOf(ConverterUtil.convertKelvinToFahrenheit(inputValue)));
type.setText("Celsius + Fahrenheit");
}
}
What I would like to do is to to have each result in a separate view in which the user can scroll, however this is where I get a little lost/confused.
I have implemented my Fragment:
Part of Main_Activity.java
class ScreenSlidePagerActivity extends FragmentActivity
{
private static final int NUM_PAGES = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new ScreenSlidePageFragment();
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
and in the activity_main.xml layout, I have replaced the out & type fields with a ViewPager:
Part of activity_main.xml
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
When called, it loads this class and displays the information using my result_slider layout:
ScreenSlidePageFragment.java
public class ScreenSlidePageFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.result_slider, container, false);
return rootView;
}
}
result_slider.xml
<com.example.temperatureconverter
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView style="?android:textAppearanceMedium"
android:padding="16dp"
android:lineSpacingMultiplier="1.2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World" />
</com.example.temperatureconverter>
How can I go about passing the data from my results to a pane in the ViewPager? Using the code below, I don't get any errors, however the app crashes with Error inflating class android.support.v4.view.ViewPager
Try following the answer to this question: How to implement a ViewPager with different Fragments / Layouts
Make sure you include the libraries and merge your MainActivity with the one from the answer.
Then in your layout file for the MainActivity, put your ViewPager
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/viewPager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Where you would like the content to scroll/go