I think I have same problem here but there is no answer.
I have an Activity with an ViewPager and a FrameLayout which will contain a Fragment. It look like this :
Activity
|— ViewPager
|-FragmentA
|— Framelayout
|— FragmentB
|— FragmentC (here I called fragmentC.setTargetFragment method).
When I rotate the device. I 'll get this error :
E/AndroidRuntime(10354): Caused by: java.lang.IllegalStateException: Fragment no longer exists for key android:target_state: index 1
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:586)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1118)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1922)
E/AndroidRuntime(10354): at android.support.v4.app.Fragment.performCreate(Fragment.java:1776)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:915)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1118)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1922)
E/AndroidRuntime(10354): at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:266)
E/AndroidRuntime(10354): at com.example.android.animationsdemo.MyActivity.onCreate(MyActivity.java:20)
Everything work fine if I don't call fragmentC.setTargetFragment method or I don't set the Adapter for the Viewpager.
Here are my Code :
Activity :
public class MyActivity extends FragmentActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
TabsAdapter tabsAdapter = new TabsAdapter(this);
mViewPager.setAdapter(tabsAdapter);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyFragmentB fragmentA = new MyFragmentB();
getSupportFragmentManager().beginTransaction().add(R.id.flContainer, fragmentA,
"TAG").addToBackStack("back").commit();
}
});
}
public static class TabsAdapter extends FragmentPagerAdapter {
private final Context mContext;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity) {
super(activity.getSupportFragmentManager());
mContext = activity;
TabInfo tabInfo = new TabInfo(MyFragmentA.class, null);
mTabs.add(tabInfo);
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public int getCount() {
return mTabs.size();
}
}
}
The Activity layout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add Fragment B"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="300dip"
android:id="#+id/flContainer" >
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:text="wrtadfa"/>
</FrameLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_below="#+id/rlContainer"
android:layout_width="match_parent"
android:layout_height="300dip" />
</LinearLayout>
And FragmentA :
public class MyFragmentA extends Fragment {
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
return myFragmentView;
}
}
FragmentA layout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment A" />
</LinearLayout>
FragmentB :
public class MyFragmentB extends Fragment implements MyFragmentC.CallBack {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);
myFragmentView.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyFragmentC fragmentA = new MyFragmentC();
//This caused the problem
fragmentA.setTargetFragment(MyFragmentB.this, 0);
getChildFragmentManager().beginTransaction().add(R.id.flContainer2, fragmentA, "TAG").addToBackStack("back").commit();
}
});
return myFragmentView;
}
}
fragment_b.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#888888"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment B" />
<TextView
android:id="#+id/c_received"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add Fragment C"/>
<FrameLayout
android:id="#+id/flContainer2"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
FragmentC :
public class MyFragmentC extends Fragment {
public static interface CallBack{
//some call back
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(getTargetFragment() != null){
CallBack callBack = (CallBack) getTargetFragment();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_c, container, false);
return myFragmentView;
}
}
fragment_c.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#888888"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment C" />
</LinearLayout>
I know that I can work around by let the Activity implement the MyFragmentC.CallBack instead of FragmentB implement it.
But I just curious why does it happen ???
If I don't set Adapter for the viewpager or don't call "setTargetFragment" in FragmentC. Then everything work fine.
So sorry because I don't know how to format the code well in here and it's a long post. Any help could be appreciate.
Please have a look into google's discussion thread where they are suggested to remove setTargetFragment() and instead use getParentFragment(). More detail is provided here : https://code.google.com/p/android/issues/detail?id=54520
I think it is about your getItem() method in your adapter. Rather then using FragmentPagerAdapter you can use FragmentStatePagerAdapter and put an if check for your getItem method. After pausing and resuming (in your case this is orientation change) probably your reference to the object get lost.
In google dev forums they also say not to use setTargetFragment method since it is buggy, you can try using getParentFragment for that reason.
Related
I am trying to change the fragment when I click on a button. The button is inside a fragment and I want to go to another fragment. This code is not giving any error but not changing to desired fragment. It is just showing the background of container. Please help me why it is just showing the color of container and not changing to new fragment.
Here is my first Fragment-
public class IntroFragment1 extends Fragment {
public IntroFragment1() {
// Required empty public constructor
}
public static IntroFragment1 newInstance() {
return new IntroFragment1();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_intro1, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/**
* Button to go to next tab in tutorial
* */
Button nextScreen = getView().findViewById(R.id.nextTabButtonIntro);
nextScreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (vb1 != null) {
vb1.vibrate(300);
}
FragmentTransaction transaction = getFragmentManager().beginTransaction();
Fragment frag = IntroFragment2.newInstance();
transaction.replace(R.id.containerIntroScreen, frag);
transaction.commit();
}
});
}//End of onViewCreated
}
This is the XML of first Fragment. The next Button should take me to next fragment-
<LinearLayout 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"
android:background="#color/colorPrimaryDark"
android:orientation="vertical"
android:weightSum="1"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroFragment1">
<TextView
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="casual"
android:text="Track your daily activities. Stay healthy, Stay smart."
android:textSize="26dp" />
<Button
android:id="#+id/skipIntoButton"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="#drawable/background_button"
android:fontFamily="casual"
android:text="skip"
android:textAllCaps="true"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
android:textColor="#000" />
<Button
android:id="#+id/nextTabButtonIntro"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="#drawable/background_button"
android:fontFamily="casual"
android:text="next"
android:textAllCaps="true"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
android:textColor="#000" />
</LinearLayout>
This is the fragment, I want to go to-
public class IntroFragment2 extends Fragment {
public IntroFragment2() {
// Required empty public constructor
}
public static android.support.v4.app.Fragment newInstance() {
IntroFragment2 fragment = new IntroFragment2();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_intro2, container, false);
}
The XML of the 2nd Fragment-
<RelativeLayout 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"
android:background="#color/colorAccent"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroFragment2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:text="2nd fragment" />
</RelativeLayout>
This is the layout of activity which has the fragments-
<?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.example.fitbitsampleapp.AppIntroTabbedView.IntroScreen">
<android.support.v4.view.ViewPager
android:background="#00F111"
android:id="#+id/containerIntroScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
So initially the app opens with 1st transaction as expected. However when I click on next button in fragment 1, it should take me to fragment 2. But it just shows the Background color of ViewPager after the Fragment Transaction.
EDIT:
Here is my Main Activity as well which has the fragments-
public class IntroScreen extends AppCompatActivity {
public static Vibrator vb1;
public Button nextScreen;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intro_screen);
/***/
vb1 = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
/**
* Create the adapter that will return a fragment
* for each of the N primary sections of the activity.
* */
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
/** Set up the ViewPager with the sections adapter.*/
ViewPager mViewPager = findViewById(R.id.containerIntroScreen);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
switch (position) {
case 0:
return IntroFragment1.newInstance();
case 1:
return IntroFragment2.newInstance();
default:
return IntroFragment2.newInstance();
}
}
#Override
public int getCount() {
return 2;
}
}
}
SOLVED BY #MikeM. in the comments above.
Since I was already using a ViewPager, All that was required was to give the correct item number to my ViewPager.
int THE_POSITION_OF_THE_FRAGMENT_IN_VIEW_PAGER = 1;
mViewPager.setCurrentItem(THE_POSITION_OF_THE_FRAGMENT_IN_VIEW_PAGER);
I am facing some issues for fragment in Android.
I completed a implementation of ViewPager using two fragment class with its xml layout, An MainActivity and An Adapter.
First Fragment : Linear Layout is Parent as well in second fragment, Linear Layout is parent. I have a button in my first fragment, i want to replace first fragment means switch fragment from first to second.
I am using ViewPager. Kindly Look on my source code.
PagerActivity.java
public class PagerActivity extends FragmentActivity {
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager);
mViewPager=(ViewPager)findViewById(R.id.viewpager);
/** set the adapter for ViewPager */
mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
// mViewPager.notify();
}
}
PagerAdapter.java
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
/** Show a Fragment based on the position of the current screen */
if (position == 0) {
return new Welcome();
}else{
return new Locate();
}
}
#Override
public int getCount() {
return 2;
}
}
Welcome.java
Fragment 1
public class Welcome extends Fragment implements GlobalInterFace, View.OnClickListener{
private Button welcomeBtn;
private View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_welcome, container, false);
welcomeBtn=(Button)v.findViewById(R.id.welcomeBtn);
findViewById();
setOnClickListener();
return v;
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.welcomeBtn:{
Log.e("click", "click");
Fragment fragment = new Locate();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.parent_linear, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
break;
}
}
}
Locate.java
Fragment 2
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_welcome_pager_two, container, false);
locateMe=(Button)v.findViewById(R.id.locateBtn);
locateMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), SignUpActivity.class);
startActivity(i);
((Activity) getActivity()).overridePendingTransition(0,0);
}
});
return v;
}
welcome xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/parent_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/splash_color"
android:weightSum="100">
<RelativeLayout
android:id="#+id/rel1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50">
<com.rey.material.widget.ImageView
android:id="#+id/welcome_Image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/welcome"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/welcomeRelativeTwo"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:padding="#dimen/universal_margin4"
>
<com.rey.material.widget.TextView
android:id="#+id/Ready"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/welcome_ready"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="#dimen/universal_margin2"
android:layout_centerInParent="true"
/>
<com.rey.material.widget.TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/welcome_descrition"
android:layout_below="#+id/Ready"
android:textAlignment="center"
android:layout_centerHorizontal="true"
android:layout_marginTop="#dimen/universal_margin"
/>
<com.rey.material.widget.Button
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/welcomeBtn"
app:rd_enable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/description"
android:text="#string/welcome_btntext"
android:textColor="#color/splash_color"
android:background="#color/colorAccent"
android:layout_marginTop="#dimen/universal_margin2"
/>
</RelativeLayout>
<!-- Your RelativeLayout Items -->
</LinearLayout>
Locate.xml
same as welcome layout only layout id is changed.
When I click on WelcomeBtn, the fragment replacement is not working.mentioned this one in my source code in Welcome.java
please help me.
Your parent parent_linearis instance of LinearLayout if you want to put fragment inside this view you should change your LinearLayout to FrameLayout something like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/parent_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/splash_color">
//... your other layout goes here
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
And change following part of your code:
fragmentTransaction.replace(R.id.fragment_container, fragment);
Halo guys, I followed the android developer steps:http://developer.android.com/training/animation/screen-slide.html
How can I call get the "btnRight" & "btnLeft" in MainJava to create a onClick function?
i have no idea about that, (???).findViewByID ?
btw, is there an another better coding design to create this effect?
i wanna create 3 page that can slide or maybe click to change screen, did i use this viewpager incorrectly? Is it probably add some new view instants of using the pagenumber trick?
please help me a bit, thanks!!
MainJava.java:
public class MainJava extends FragmentActivity {
private static final int NUM_PAGES = 3;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();
actionBar.hide();
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(1);
}
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;
}
}
}
ScreenSlidePageFragment.java:
public class ScreenSlidePageFragment extends Fragment {
public static final String ARG_PAGE = "page";
private int mPageNumber;
public static ScreenSlidePageFragment create(int pageNumber) {
ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
fragment.setArguments(args);
return fragment;
}
public ScreenSlidePageFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
ViewGroup rootView = (ViewGroup) inflater
.inflate(R.layout.scroll_view_content, container, false);
//rootView.addView(inflater.inflate(R.layout.scroll_view_content, null));
View pageLeft = (View) rootView.findViewById(R.id.pageLeft);
View pageRight = (View) rootView.findViewById(R.id.pageRight);
View pageMain = (View) rootView.findViewById(R.id.pageMain);
if (mPageNumber==0){
pageLeft.setVisibility(View.VISIBLE);
pageMain.setVisibility(View.GONE);
pageRight.setVisibility(View.GONE);
}else if (mPageNumber==1){
pageLeft.setVisibility(View.GONE);
pageMain.setVisibility(View.VISIBLE);
pageRight.setVisibility(View.GONE);
}else if (mPageNumber==2){
pageLeft.setVisibility(View.GONE);
pageMain.setVisibility(View.GONE);
pageRight.setVisibility(View.VISIBLE);
}
return rootView;
}
public int getPageNumber() {
return mPageNumber;
}
scroll_view_content.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Dummy content. -->
<LinearLayout
android:id="#+id/pageLeft"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="?android:textAppearanceMedium"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:lineSpacingMultiplier="1.2"
android:text="AAA" />
</LinearLayout>
<LinearLayout
android:id="#+id/pageRight"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="?android:textAppearanceMedium"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:lineSpacingMultiplier="1.2"
android:text="CCC"/>
</LinearLayout>
<RelativeLayout
android:id="#+id/pageMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#123456"
android:orientation="vertical" >
<TextView
android:id="#+id/textB"
style="?android:textAppearanceMedium"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.2"
android:background="#654321"
android:text="BBB"/>
<LinearLayout
android:layout_below="#+id/textB"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id="#+id/btnLeft"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#00ffff"
android:text="A"/>
<Button
android:id="#+id/btnRight"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#ffff00"
android:text="B"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
Thats simple really. You have to use the setCurrentItem(int) of the view pager class. The algorithm would be:
int currPage=1 //Points to second page in the viewpager
if left button clicked //listener for the button
2a. currPage--
2b. mPager.setCurrentItem(currPage) //pager is object of your viewpager class
if right button clicked //listener for the button
3a. currPage++
3b. mPpager.setCurrentItem(currPage)
Check out this link for for info.
this is my first fragment which open a fragment through xml layout
public class ListFrag extends SherlockFragment implements OnItemClickListener
{
Context c;
List<ReferalRow> referal_RowItems;
DoctorDaoImpl doctorDao;
DoctorServiceImpl service;
DoctorValidator doctorValidator;
View layoutView;
ListView doctoListView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
layoutView = inflater.inflate(R.layout.activity_refer_mangmnt, null);
return layoutView;
}
and this is my activity_refer_mangmnt.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="2"
android:padding="2dp">
<ListView
android:id="#+id/listView_refer_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dividerHeight="1dp"
android:divider="#android:color/black"
android:choiceMode="singleChoice"
android:listSelector="#drawable/list_selector" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/rightpanel_back">
<fragment
android:id="#+id/detail_fragment"
android:tag="detailfrag"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.app1.DetailsFrag" />
</LinearLayout>
`</LinearLayout>
and this is my DetailFrag class
public class DetailsFrag extends SherlockFragment
{
ExpandableListView detailList;
TextView tvMessage;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
contentView = inflater.inflate(R.layout.activity_refer_view, null);
detailList = (ExpandableListView) contentView.findViewById(R.id.ep_detail_view);
tvMessage = (TextView)contentView.findViewById(R.id.tv_textView);
return contentView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
if(id==0)
{
detailList.setVisibility(View.GONE);
tvMessage.setText("Click on the item on the left panel to view the details");
}
else
{
detailList.setVisibility(View.VISIBLE);
tvMessage.setVisibility(View.GONE);
}
and this is my onItem click listener in LIstFrag
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment lastFrag = getFragmentManager().findFragmentByTag("detailfrag");
if(lastFrag!=null)
ft.remove(lastFrag);
Fragment fragment = Fragment.instantiate(c, DoctorDetailsFrag.class.getName(),arguments);
ft.replace(R.id.detail_fragment, fragment);
ft.commit();
i need when first time i want to display a message in the right panel after click on the item in the list i want to disappear that message. but here the message is not remove from the fragment. its displayed in the backgrnd of new fragment. y it is?
Try:
ft.addToBackStack(null)
after you call: ft.remove(lastFrag);
Perhaps this link can help you to understand this transaction:
http://developer.android.com/guide/components/fragments.html#Transactions
Another way is to to reuse your lastFrag when it's not null. Then you need a method in your DetailFrag that is called from your clickListener.
In a class i am adding a Fragment programatically.
This Fragment contains a Button, which i want to have an onClick implementation.
Here is the class i have:
public class ShareProduct extends SherlockFragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.share_product);
FragmentManager fragmentManager = getSupportFragmentManager();
final FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
ProductFragment1 fragment = new ProductFragment1();
fragmentTransaction.add(R.id.share_product_parent, fragment);
fragmentTransaction.commit();
Button done_button = (Button) fragment.getView().findViewById(
R.id.done_product_1);
done_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
ProductFragment2 fragment = new ProductFragment2();
fragmentTransaction
.replace(R.id.share_product_parent, fragment);
fragmentTransaction.commit();
}
});
}
}
and my ProductFragment1 class is:
public class ProductFragment1 extends SherlockFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater
.inflate(R.layout.share_product_1, container, false);
return view;
}
}
and the layout my main class uses is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/share_product_parent"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="right|center_vertical"
android:orientation="horizontal" >
</RelativeLayout>
and the layout my ProductFragment1 uses is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tv1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25dp" />
<EditText
android:id="#+id/et1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/tv1"
android:textSize="25dp" />
<Button
android:id="#+id/done_product_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/et1"
android:text="Done" />
</RelativeLayout>
The problem is:
I am getting a NullPointerException at this line in my main class:
Button done_button = (Button) fragment.getView().findViewById(R.id.done_product_1);
done_button.setOnClickListener ....
when i searched for what getView() on a fragment returns. I found out that it returns the view from onCreateView();
I checked it doesn't return null.
Thank You
You are on the wrong track here. You get the NPE because the Fragments views is not created yet. Fragments also have a lifecycle just like Activities.
What you should be doing is assigning the OnClickListener inside your Fragments onViewCreated() method. And from there... you should create a callback and notify your hosting Activity of the event.