I am making a view pager to make a slide show for images. I took code from Android developers, but I was facing some issues, fragment was not recognized, I think it was because my android was 2.33. So to solve that I imported a jar file android.support.v4.jar
My issues were resolved but now I am getting this error that getfragmentmanager() is undefined
and another issue "The method invalidateOptionsMenu() is undefined for the type new ViewPager.SimpleOnPageChangeListener(){}"
Here is my code, can any one please help ??
My platform is 2.3.3 and api level is 10 and in manifest I have this
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
Code :
package com.example.profilemanagment;
import android.support.v4.app.Fragment;
import android.support.v4.app.*;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
public class ScreenSlideActivity extends FragmentActivity {
/**
* The number of pages (wizard steps) to show in this demo.
*/
private static final int NUM_PAGES = 5;
/**
* The pager widget, which handles animation and allows swiping horizontally to access previous
* and next wizard steps.
*/
private ViewPager mPager;
/**
* The pager adapter, which provides the pages to the view pager widget.
*/
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_slide);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When changing pages, reset the action bar actions since they are dependent
// on which page is currently active. An alternative approach is to have each
// fragment expose actions itself (rather than the activity exposing actions),
// but for simplicity, the activity provides the actions in this sample.
invalidateOptionsMenu();
}
});
}
/**
* A simple pager adapter that represents 5 {#link ScreenSlidePageFragment} objects, in
* sequence.
*/
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return ScreenSlidePageFragment.create(position);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
Quoting from the docs.
When using this class (FragmentActivity) as opposed to new platform's built-in fragment and loader support, you must use the getSupportFragmentManager() and getSupportLoaderManager() methods respectively to access those features.
Since you are extending FragmentActivity use getSupportFragmentManager()
http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html
Check the docs
FragmentActivity does not have getFragmentManager()
Related
I started a new project on Android Studio using Tabbed Activity. I did not change any code but what I observed is, when you swipe between the tabs then the name of the current active tab is not showing. I want the name to be shown up always. How can I do this?
I post the default code which is delivered automatically by Android Studio. I think the method getPageTitle is responsible for this.
import android.content.Context;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import com.example.customerservice.R;
/**
* A [FragmentPagerAdapter] that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
// Show 2 total pages.
return 3;
}
}
Open a new project
choose "Tabbed Activity"
open "SectionsPagerAdapter" Java class:
Click on "Tab 1" and "Tab 2"
you can see that the names of Tabs are stored in String resources
you can find it here:
then you can change it for example:
Hello Tab 1
Hello Tab 2
This is the result:
Edited:
If you want to see all the tabs names at the same time, you can use "ViewPager2", read this documentation:
Create swipe views with tabs using ViewPager2
I hope this is helpful.
I have the following code, the project is migrated to andoidx, R.id.viewpager returns can not find symbol variable viewpager SimpleFragmentPagerAdapter is a custom(an extention of)
FragmentPagerAdapter and is working well
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the content of the activity to use the activity_main.xml layout file
setContentView(R.layout.activity_catagory);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown on each page
SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager());
// Set the adapter onto the view pager
viewPager.setAdapter(adapter);
}
}
I have a Main Activity which uses an AHBottomNavigationView for a menu at the bottom of the screen. When a different menu item is clicked, it creates a new fragment corresponding to that menu item with logic like so (condensed switch statement for the simplicity of this question):
fragmentManager.beginTransaction().replace(R.id.content_id, New TheFragmentForTheTabClicked).commit();
Where content_id is the ID of the Main Activity's ConstraintLayout.
Within the fragment for my first navigation menu item, there are two more tabs (using TabLayout), which replace the screen space with another fragment. This is done with a FragmentPagerAdapter, which is set onto a ViewPager, so tapping each tab changes the sub fragment. So at this point, there is a fragment nested in a fragment nested in a class. Here is what it generally is:
Main Activity
|
+-- Fragment 1 (selected from AHBottomNavigationView)
| |
| +-- Sub-Fragment 1 (selected by clicking the first tab in Fragment 1)
| |
| +-- Sub-Fragment 2 (selected by clicking the second tab in Fragment 1)
|
+-- Fragment 2 (selected from AHBottomNavigationView)
|
+-- Fragment 3 (selected from AHBottomNavigationView)
|
+-- Fragment 4 (selected from AHBottomNavigationView)
So my question is this:
Is the way I am doing this correct, and if not, what would a better way be?
Also, I'm finding that When I tab to Fragment 1 the first time, the swiping and tapping between the two tabs works fine, however if I tap a different bottom navigation menu item (i.e. Fragment 3) and then go back, I get the following 2 issues:
The content in either of the subfragments is not shown
Swiping between the two tabs no longer works. Instead of one motion moving to the different tab, I have to pull across the screen entirely because the indicator gets "stuck" part way between two tabs.
If there is any more information that I can provide, please let me know and I will.
Fragment1.java:
package com.mypackage.mypackage;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
*/
public class Fragment1 extends Fragment {
private FragmentActivity mContext;
public Fragment1() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_1, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
// Find the view pager that will allow the user to swipe between fragments
ViewPager viewPager = (ViewPager) getView().findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown on each page
// using getFragmentManager() will work too
Fragment1PagerAdapter adapter = new Fragment1PagerAdapter(mContext.getSupportFragmentManager(), mContext);
// Set the adapter onto the view pager
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) getView().findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
}
/**
* Override to set context. This context is used for getSupportFragmentManager in onCreateView
* #param activity
*/
#Override
public void onAttach(Activity activity) {
mContext=(FragmentActivity) activity;
super.onAttach(activity);
}
}
fragment_1.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabBackground="#color/fragment1TabBackground"
app:tabIndicatorColor="#color/fragment1TabIndicatorColor"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Fragment1PagerAdapter.java
package com.mypackage.mypackage;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.content.Context;
public class Fragment1PagerAdapter extends FragmentPagerAdapter {
private Context context;
public Fragment1PagerAdapter(FragmentManager fm, Context mContext){
super(fm);
context = mContext;
}
#Override
public Fragment getItem(int position){
if (position == 0){
return new SubFragment1();
}
else{
return new SubFragment2();
}
}
#Override
public int getCount() {return 2;}
#Override
public CharSequence getPageTitle(int position) {
switch(position){
case 0:
return context.getResources().getString(R.string.sub_fragment_1_page_title);
case 1:
return context.getResources().getString(R.string.sub_fragment_2_page_title);
default:
return null;
}
}
}
When nesting Fragments inside Fragment with ViewPager and swipe feature as FragmentManager which needs to be provided to Adapter recommended is to use: getChildFragmentManager() instead of getSupportFragmentManager() or getFragmentManager(). Because both are actually related to Activities instead of getChildFragmentManager(), as documentation says, is related to Fragment:
Return a private FragmentManager for placing and managing Fragments
inside of this Fragment.
I want to display custom listview in navigation drawer's fragment page. However, in my fragment class, I'm getting an error which seems I cannot set a custom adapter.
package android_gcm_client.mynavigation;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
public class List_Fragment extends Fragment {
View rootview;
ArrayList prgmName;
public static int [] prgmImages= {R.drawable.images,R.drawable.images1,R.drawable.images2,R.drawable.images3,R.drawable.images4,R.drawable.images5,R.drawable.images6,R.drawable.images7,R.drawable.images8};
public static String [] prgmNameList={"Let Us C","c++","JAVA","Jsp","Microsoft .Net","Android","PHP","Jquery","JavaScript"};
#Nullable
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview=inflater.inflate(R.layout.custom_layout,container,false);
CustomAdapter ca = new CustomAdapter(this,prgmNameList,prgmImages);
ListView listview=(ListView) getView().findViewById(R.id.listView);
listview.setAdapter(ca);
return rootview;
}
}
It seems the error happens in line below (custom adapter can not be applied).
CustomAdapter ca = new CustomAdapter(this,prgmNameList,prgmImages);
In MainActivity I call the fragment as follows:
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Fragment objFragment=null;
switch(position) {
case 0:
objFragment=new ListFragment();
break;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, objFragment)
.commit();
}
I tried different ways to display custom listview for navigation item selected method.
I tried to directly call activity instead of fragment but problem was navigation drawer not visible for all activity. So I tried to call CustomAdapter in activity as I'm doing in fragment.
I have struggle to solve this error. (Sorry for bad English).
You are using this in custom adapter. Usually adapters wants a Context in constructor call. But this constructor is called inside a fragment and this can't be used.
You can use getActivity() as Context inside a Fragment. But.
Sometimes it can return a null if it is called before onAttach() of this fragment.
CustomAdapter ca = new CustomAdapter(getActivity(), prgmNameList, prgmImages);
Also you can use Application context by creating static variable inside your Application class:
public class Application extends android.app.Application {
public static Context AppContext = null;
#Override
public void onCreate() {
super.onCreate();
AppContext = getApplicationContext();
// You can use this line to solve styling problems
// because Manifest android:theme is not working
AppContext.setTheme(R.style.AppTheme);
}
}
and create adapter like this:
CustomAdapter ca = new CustomAdapter(Application.AppContext, prgmNameList, prgmImages);
Can anyone tell me why this isnt working? I havent changed this file since it worked last but now I get the error below:
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity {
private final static int NUM_PAGES = 2;
private ViewPager mPager;
private ScreenSlidePagerAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
mAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(2);
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment frag = null;
switch (i) {
case 0:
frag = new PageOneFragment();
break;
case 1:
frag = new PageTwoFragment();
break;
}
return frag;
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
The error is on "frag = new PageTwoFragment();" which states "Type mismatch: cannot convert from PageTwoFragment to Fragment".
Maybe I should create two projects from now on, last good version and then current working project. Is this something other people do?
Thanks
The Problem is, that you are mixing Android Fragments how there were introduced in API11 and Fragments from android support library.
You have to use one or the other, but not both.
Change your imports to
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
And change getFragmentManager() to getSupportFragmentManager().
And it will work using the support lib.
Calling mPager.setCurrentItem(2); with a pager of 2 Fragments crashs, though.
Only 0 and 1 are valid values in your case.
You imported the wrong Fragment.
You need to import android.support.v4.Fragment
Furthermore, your adapter only handles 2 Fragments. Therefore calling
ViewPager.setCurrentItem(2);
will cause problems, since the index for the first fragment is 0.