Android Studio ViewPager with navigation - java

I have this situation:
Fragment1 uses viewPager, then when click some component inside the viewPager's child fragment, it open Fragment2, which also uses viewPager.
So far so good. But then, on click the back button, doesn't come back to Fragment1, coming back for my main activity instead. The app uses single activity and Android Navigation.
I already tried use viewPager2, it happens the same thing.
Thanks if anyone can help me.
public class Fragment1 extends AbstractNavFragment {
private Fragment1 binder;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binder = Fragment1Binding.inflate(inflater, container, false);
return binder.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
binder.viewPager.setAdapter(new PageAdapterInternal(getChildFragmentManager()));
binder.viewPager.setOffscreenPageLimit(2);
binder.tabLayout.getTab().setupWithViewPager(binder.viewPager);
}
public void navigateToFragment2() {
navigate(R.id.action_Fragment1_to_Fragment2);
}
private class PageAdapterInternal extends FragmentStatePagerAdapter {
public PageAdapterInternal(#NonNull FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new IrcSupplyPositionsFragment(IrcSupplyPositionsFragment.FragmentType.PENDING);
case 1:
return new IrcSupplyPositionsFragment(IrcSupplyPositionsFragment.FragmentType.COMPLETED);
default:
throw new IllegalStateException("Unexpected value: " + position);
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return translate("rotativeInventory.supply.pendingPositions");
case 1:
return translate("rotativeInventory.supply.positionsCompleted");
default:
return "";
}
}
#Override
public int getCount() {
return 2;
}
}
}
public class Fragment2 extends AbstractNavFragment {
private Fragment2 binder;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binder = Fragment2Binding.inflate(inflater, container, false);
return binder.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
binder.viewPager.setAdapter(new RotativeInventorySupplyUDFragment.PageAdapterInternal(getChildFragmentManager()));
binder.viewPager.setOffscreenPageLimit(2);
binder.tabLayout.getTab().setupWithViewPager(binder.viewPager);
}
#Override
protected void doOnViewCreate() {}
private class PageAdapterInternal extends FragmentStatePagerAdapter {
public PageAdapterInternal(#NonNull FragmentManager fm) {
super(fm);
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new IrcSupplyUDFragment(IrcSupplyUDFragment.FragmentType.PENDING);
case 1:
return new IrcSupplyUDFragment(IrcSupplyUDFragment.FragmentType.COMPLETED);
default:
throw new IllegalStateException("Unexpected value: " + position);
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return translate("rotativeInventory.supply.pendingPositions");
case 1:
return translate("rotativeInventory.supply.positionsCompleted");
default:
return "";
}
}
#Override
public int getCount() {
return 2;
}
}
}

You have to override your onBackPressed method of your Activity, to controll all this stuff or register your fragment for a OnBackPressedDispatcher and when user click on back button of your device, take a decision, like ==> findNavController().popBackStack()

Related

Use a view from a fragment in main activity

I'm pretty new in android development and I have some questions about communication between fragments and main activity.
I didn't success to solve my problem in my particular case. What I want to do is to modify the alpha of a view inside a fragment (something like a card) when scrolling from one fragment to the one with this view. I tried different things but I failed (null pointer exception), you can see some experiments in a comment. Here is my code and my architecture:
Fragment with the view:
public class VideoviewFragment extends BaseFragment {
/* public View card;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.fragment_videoview, container, false);
card = (View) rootview.findViewById(R.id.card_video);
return rootview;
}
public void setalphacard(float value){
card.setAlpha(value);
}*/
public static VideoviewFragment create() {
return new VideoviewFragment();
}
#Override
public int getLayoutResId() {
return R.layout.fragment_videoview;
}
#Override
public void inOnCreateView(View root, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
}
}
Base fragment:
public abstract class BaseFragment extends Fragment {
private View mRoot;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mRoot = inflater.inflate(getLayoutResId(), container, false);
inOnCreateView(mRoot, container, savedInstanceState);
return mRoot;
}
#LayoutRes
public abstract int getLayoutResId();
public abstract void inOnCreateView(View root, #Nullable ViewGroup container,#Nullable Bundle savedInstanceState);
}
Main Activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Viewpager
final ViewPager viewPager = (ViewPager) findViewById(R.id.am_view_pager);
final MainPagerAdapter adapter = new MainPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
// tabview et viewpager
viewPager.setCurrentItem(1);
// Changement couleurs swipe
viewPager.setBackgroundColor(Color.rgb(135,206,250));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 1) {
viewPager.setBackgroundColor((Integer) new ArgbEvaluator().evaluate(positionOffset, Color.rgb(135,206,250),Color.rgb(240,15,45)));
//videoviewFragment.setalphacard(positionOffset);
}
if(position == 0) {
viewPager.setBackgroundColor((Integer) new ArgbEvaluator().evaluate(positionOffset, Color.TRANSPARENT,Color.rgb(135,206,250)));
}
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
Adapter:
public class MainPagerAdapter extends FragmentPagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return CameraFragment.create();
case 1:
return OptionFragment.create();
case 2:
return VideoviewFragment.create();
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
XML VideoviewFragment
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativeLayout0"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/card_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="70dp"
android:background="#drawable/card_background_video"/>
</RelativeLayout>
(I know there is no instance of my fragment in this activity...)
I found few similar topics on StackOverflow like this one Use view from fragment xml file, but I'm doing something wrong...
Thanks for your help!

Android , Fragments into fragment into activity communication

This is my problem.In my android app I have "Activity 1" that contains "fragment1". "Fragment1" in his layout contains a "viewpager" with 3 pages "fragment3", "fragment4" and "fragment5". I "Activity 2" that contains "Fragment2". Now I want to execute an action in "Fragment" 1, 2 or 3 and then launch the activity2, so send data from fragments 3,4 or 5 and display them in the fragment 6. I am willing to go through "interfaces" who will be in the fragments 3, 4, 5 to respect the java standards. Since, I can not, I get errors. In landscape mode the fragments 2 and 3 are side by side
For example here are
Fragment1
public class Frag1 extends Fragment implements Frag3.Communicator{
private ViewPager mPager = null;
private TabLayout mTab = null;
MyAdapter adapter;
private int p;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag4, container, false);
mPager = (ViewPager) v.findViewById(R.id.viewPager);
mTab = (TabLayout) v.findViewById(R.id.tabLayout);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
mPager.setAdapter(new MyAdapter(fragmentManager));
mTab.setupWithViewPager(mPager);
return v;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void respond(String data) {
}
class MyAdapter extends FragmentStatePagerAdapter
{
public MyAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if(position == 0)
{
fragment = new Frag1();
p = position;
}
if(position == 1)
{
fragment = new Frag2();
p = position;
}
if(position == 2)
{
fragment = new Frag3();
p = position;
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
if(position == 0)
{
return "Tab 1";
}
if(position == 1)
{
return "Tab 2";
}
if(position == 2)
{
return "Tab 3";
}
return null;
}
}
}
Fragment 3
public class Frag3 extends Fragment {
Button b;
Communicator comm;
public void setCommunicator(Communicator c)
{
comm = c;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag1, container, false);
return v;
}
public interface Communicator
{
public void respond(String data);
}
public void openSub()
{
comm.respond("Sub ouvert depuis le fragment numéro 1");
}
}
Fragment2
public class Frag2 extends Fragment {
private TextView tv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag5, container, false);
tv = (TextView) v.findViewById(R.id.frag5Tv);
return v;
}
public void changeData(String data)
{
tv.setText(data);
}
}
I believe you should unify architecture either with one Activity or with two Activities but for both orientations. In case with one Activity you can communicate via Activity's interface. Just replace Fragment1 with Fragment2 to change view.
In case with two Activities you can communicate via startActivityForResult/onActivityResult methods.

Unable to call Fragment's Method from Parent View

I am trying to call a Fragment's public Method from its Parent View and I followed this, this and these questions on Stack. However the method I need is not avilable when I try to call it from the Parent view.
Here's my code:
Fragment:
public class FirstTabView extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_first_tab_view, container, false);
return rootView;
}
//The method I need to call
public void PostStuff(String caption){
}
}
Parent View: (Which contains the Main View Pager)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_view);
pager = (ViewPager) findViewById(R.id.mainpager);
mAdapter = new HomePagerAdapter(getSupportFragmentManager());
pager.setAdapter(mAdapter);
pager.setOffscreenPageLimit(4);
//Getting the Fragment's Tag. o is the Pager's Fragment index. i.e.: The first fragment
String fragment_tag = "android:switcher:" + pager.getId() + ":" + 0;
FirstTabView fragment = (FirstTabView) getSupportFragmentManager().findFragmentByTag(fragment_tag);
fragment. <This is where I need to call the method and pass the parameter> ();
//The method however doesn't appear when I try to reference it
}
Am I calling the Fragment's method correctly from my Parent View? What am I doing wrong?
EDIT
This is the adapter that I used to push the Fragments:
public class HomePagerAdapter extends FragmentPagerAdapter {
public HomePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstTabView();
case 1:
return new SecondTabView();
case 2:
return new ThirdTabView();
case 3:
return new FourthTabView();
case 4:
return new FifthTabView();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 5;
}
}
You can save a reference of the FirstTabView to your MainActivity, then call the method of the fragment.
FirstTabView
public class FirstTabView extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_first_tab_view, container, false);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
//set this fragment to your MainActivity
MainActivity mainActivity = (MainActivity)getActivity();
mainActivity.setFirstTabView(this);
}
//The method I need to call
public void PostStuff(String caption){
}
}
MainActivity
private FirstTabView firstTabView;
#Override
public void onCreate(Bundle bundle) {
........
if(firstTabView != null) {
firstTabView.PostStuff("Hello World");
}
}
public void setFirstTabView(FirstTabView firstTabView){
this.firstTabView = firstTabView
}

ViewPage - Change the icon on the text

I faced with a problem I can not solve. How can you replace icons in the text resource. Let's say instead of the first icons - current , the second icon - finished .
public class ViewPageAdapter extends FragmentPagerAdapter implements PagerSlidingTabStrip.CustomTabProvider {
private Context mContext;
private final int[] ICONS = {
R.drawable.selector_icon_active,
R.drawable.selector_icon_inactive
};
public ViewPageAdapter(FragmentManager fm, Context context) {
super(fm);
mContext = context;
}
#Override
public void tabUnselected(View view) {
view.setSelected(false);
}
#Override
public void tabSelected(View view) {
view.setSelected(true);
}
#Override
public View getCustomTabView(ViewGroup parent, int position) {
FrameLayout customLayout = (FrameLayout) LayoutInflater.from(mContext).inflate(R.layout.custom_tab, parent, false);
((ImageView) customLayout.findViewById(R.id.image)).setImageResource(ICONS[position]);
return customLayout;
}
#Override
public CharSequence getPageTitle(int position) {
// return null;
return super.getPageTitle(position);
}
#Override
public int getCount() {
return ICONS.length;
}
#Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
switch (position) {
case 0:
default:
bundle.putSerializable("TYPE", NotificationsType.ACTIVE);
break;
case 1:
bundle.putSerializable("TYPE", NotificationsType.INACTIVE);
break;
}
Fragment fragment = new TabFragment();
fragment.setArguments(bundle);
return fragment;
}
}

SectionsPagerAdapter - No view found for id for fragment

I have a App with a Slidingmenu where i can pick different Fragment, which displays different kind of ListFragments.
The ListFragments will be filled by JSON from my Database Server.
If you Click on one of the Listitems, a new Fragment is shown which contains more Details about the selected Listitem.
public void updateList(final Activity a, final ListFragment L) {
adapter = new SimpleAdapter(a, mCommentList,
R.layout.single_comment, new String[] {TAG_PIC_ID,TAG_CATEGORY, TAG_ACTIVITY, TAG_DATUM, TAG_AKTUSR, TAG_MAXUSR, TAG_GENDER, /*TAG_POST_ID,*/ TAG_TITLE, TAG_MESSAGE,
TAG_USERNAME }, new int[] { R.id.imgrow, R.id.category, R.id.activity/*R.id.id*/ , R.id.datum, R.id.aktusr, R.id.maxusr, R.id.gender, /*R.id.category,*/ R.id.title, R.id.message,
R.id.username });
L.setListAdapter(adapter);
ListView lv = L.getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int intid = (int)id;
Details nextFrag= new Details();
L.getFragmentManager().beginTransaction()
.replace(R.id.frame_container, nextFrag, "Test")
.addToBackStack(null)
.commit();
}
});
}
When i call the function from a "single" fragment its no problem and the DetailPage is shown.
The Problem is when i call the function from a TabbedActivity with a SectionsPagerAdapter.
The TabbedActivity
package info.androidhive.slidingmenu;
public class TabbedActivity extends Fragment {
SectionsPagerAdapter mSectionsPagerAdapter;
public static final String TAG = TabbedActivity.class.getSimpleName();
ViewPager mViewPager;
public static TabbedActivity newInstance() {
return new TabbedActivity();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_item_one, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
return v;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new newEntrys();
switch (position) {
case 0:
fragment = new newEntrys();
break;
case 1:
fragment = new oldEntrys();
break;
default:
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Aktuelle Einträge";
case 1:
return "Vergangene Einträge";
}
return null;
}
}}
The TabbedActivity contains the 2 Fragments newEntry and oldEntry which are nearly equal.
package info.androidhive.slidingmenu.fragments;
public class RegisterdEvents_new extends ListFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.read, container, false);
return rootView;
}
public void startTask(){
Read SO = new Read();
Load LEvt = SO.new Load(getActivity(), this, "NEW");
LEvt.execute();
}
public void onResume() {
startTask();
super.onResume();
}
}
So the function updateList above is called in
Load LEvt = SO.new Load(getActivity(), this, "NEW");
But the problem is that i always get the Error
No view found for id 0x7f0a000f (package:id/frame_container) for fragment Details{e3992e2 #0 id=0x7f0a000f Test}
Someone of you can help me to solve this problem?

Categories

Resources