Android + Create Fragment in ViewPager and show as Popup - android

I am new into Android and I like to code. I just got the requirement to show the screen like this.
User Inerface
My understanding is, there is an Activity which contains ViewPager and ViewPager having multiple Fragments which opened as Popup Dialog.
So I created Activity like this.
public class MainActivity extends AppCompatActivity {
private ViewPager viewPagerMain;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
findViewByIds();
setupImageSlider();
}
private void findViewByIds()
{
viewPagerMain = (ViewPager) findViewById(R.id.viewPagerMain);
}
private void setupImageSlider()
{
viewPagerMain.setAdapter(new MyStatePagerAdapter(getSupportFragmentManager()));
}
static class MyStatePagerAdapter extends FragmentStatePagerAdapter
{
public MyStatePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return OfferFragment.init();
}
#Override
public int getCount() {
return 4;
}
}
}
For now just to show dummy pages I am passing fix size as 4 in getCount()
Here is my OfferFragment class
public class OfferFragment extends Fragment {
private View view;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_offer, container, false);
return view;
}
public static OfferFragment init() {
OfferFragment offersFragment = new OfferFragment();
Bundle args = new Bundle();
offersFragment.setArguments(args);
return offersFragment;
}
}
Here are my some thoughts why I created init() method in Fragment class. As I don't know how many pages will have to be shown, in that case creating Fragment object may cause exception.
I know there is DialogFragment class which shows Fragment as Dialog. but in my case I am calling init() from Activity class and inside init() creating object of Fragment class.
So if I extend DialogFragment then, I have to call setShowDialog() method inside onCreate() of Fragment and it give me below error.
Caused by: java.lang.IllegalStateException: DialogFragment can not be attached to a container view
Kindly let me know how to Create Fragment in ViewPager and show as Popup
Thanks in Advance

Related

Moving Data from Activity to Another Activity's TabFragment's Fragment

I want to move some data from my Mainactivity to a Fragment...which is inside a tab fragment (which handles a SectionPagerAdapter)....which is inside a fragment in Mainactivity2.
I feel its too complicated and cant get it done.
GameEndedActivity (See wrong and correct variable...these are to be transferred)
public class GameEndedActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_ended);
int correct = getIntent().getIntExtra("correct", 0);
int wrong = getIntent().getIntExtra("wrong", 0);
}
}
TabFragment
public class TabFragment extends Fragment {
private int tabsCount;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_tab, container, false);
if(this.getContext() instanceof ChallengeOverviewActivity){
tabsCount = 2;
} else {
tabsCount = 3;
}
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this.getContext(), getFragmentManager(), tabsCount);
ViewPager viewPager = view.findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = view.findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
return view;
}
}
ResultFragment (Transfer data here - wrong and correct variables)
public class ResultDetailsFragment extends Fragment {
private TextView tvWrong, tvCorrect;
private AnswerListener answerListener;
public interface AnswerListener {
public void correct(int i);
public void wrong(int i);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_result_details, container, false);
tvCorrect = view.findViewById(R.id.tvCorrect);
tvWrong = view.findViewById(R.id.tvWrong);
return view;
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
if (context != null) {
answerListener = (AnswerListener) context;
}
}
}
One way to do this is the add arguments to the fragment when you create an instance of it. In your activity when you create the fragment you want to attach you add some arguments to it. These arguments can then be accessed from the fragments onCreate method.
Just do this same thing again when you are in your fragment and create your second one.
Check this answer out which explains more in detail how to do it: https://stackoverflow.com/a/17436739/964887

moving from one fragment to another using viewpager

So currently my code can move between objects from the same fragment, but I want to move between different fragments that have different layouts.What code do I need to add to viewpager to make it work? Do I need to make use of a FragentManager? Can anyone guide me on how to go about it? Thanks.
Below if my code:
ScreenSlidePagerActivity.java
public class ScreenSlidePagerActivity extends FragmentActivity {
private static final int NUM_PAGES = 5;
private ViewPager mPager;
private PagerAdapter pagerAdapter;
/**
* The pager adapter, which provides the pages to the view pager widget.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slide_screen_viewpager);
//declare viewpager and pageradapter
mPager = findViewById(R.id.ViewPageSlide);
pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(pagerAdapter);
}
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0){
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
}
else {
mPager.setCurrentItem(mPager.getCurrentItem() -1 );
}
}
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;
}
}
}
ScreenSlidePageFragment.java
public class ScreenSlidePageFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.slide_content_page, container, false
);
return rootView;
}
}
You have only one class i.e.,ScreenSlidePageFragment that extends fragments. If you want different layouts for that, its better if you create different classes that inflates different layouts. eg: if you want two layouts, create two classes and both classes should inflate different layouts. The changes need to be done are :
//inside ScreenSlidePagerAdapter
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new ScreenSlidePageFragment();
case 1:
return new NewClass();
//and so on
}
}
You have to create the new Class similar to ScreenSlidePageFragment. The only change is inflate a different layout.
public class NewClass extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.new_layout, container, false
);
return rootView;
}
}
You can create a new_layout similar to slide_content_page and customize it as you want. You can also increase the no of fragment objects and layout as you wish.
But a new way of doing this things has come. Its better if you extend FragmentStateAdapter instead of FragmentStatePagerAdapter. This is more easy and efficient. You have to override createFragment in this case instead of getItem. Ignore of you are okay with it.
Hope this is the question you have asked and this helps. Thankyou.

Get to a function on a fragment

I am trying to get to a function on a fragment.
Please look at the function msgFromTopFragment at main activity.
The declaration of bottomFragment results in an error message – incompatible types.
And I can’t understand why. How can I fix it?
public class MainActivity extends AppCompatActivity
implements TopFragment.onBtnListener{
TopFragment topFragment = new TopFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}//onCreate
#Override
public void msgFromTopFragment(String msg) {
BottomFragment buttomFragment = getFragmentManager().findFragmentById(R.id.bottomFragment);
buttomFragment.updateResult(msg);
}//msgFromTopFragment
}//MainActivity
Code for bottom fragment:
public class BottomFragment extends Fragment {
TextView resultTv;
public BottomFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_bottom, container, false);
resultTv = view.findViewById(R.id.resultTv);
return view;
}
public void updateResult(String msg){
resultTv.setText(msg);
}
}//BottomFragment
BottomFragment buttomFragment = (BottomFragment) getSupportFragmentManager().findFragmentById(R.id.bottomFrag‌​ment);
this solved it :) thank you

ViewPager + FragmentPagerAdapter inside a DialogFragment gets "IllegalArgumentException:No view found..."

I am trying to show a FragmentDialog ( created and shown as a dialog NOT added as content in a view hierarchy) where there is a ViewPager whose content is given by a FragmentPagerAdapter (provides Fragments consisting of an image).
The code works perfect when showing ViewPager + FragmentPagerAdapter from a FragmentActivity, but get the following exception when doing it from a FragmentDialog:
"IllegalArgumentException: No view found for id 0x7f040077 for fragment SimpleFragment..."
Here is my code:
A SherlockFragmentActivity with a button to create and show the dialog.
public class BorrameActivity extends SherlockFragmentActivity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one_act);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
showTheDialog();
}});
}
private void showTheDialog(){
AchGalleryDialog newFragment = AchGalleryDialog.newInstance(achs);
newFragment.show(getSupportFragmentManager(), "dialog");
}
The FragmentDialog:
public class AchGalleryDialog extends DialogFragment{
public AchGalleryDialog(){
}
public static AchGalleryDialog newInstance(){
AchGalleryDialog f = new AchGalleryDialog();
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_user_result, container);
getDialog().setTitle("Hola tronco");
//content to show in the fragments
int[] images = new int[]{R.drawable.d1, R.drawable.d2, R.drawable.d3};
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
MyFragmentAdapter adapter = new MyFragmentAdapter(getFragmentManager(),images);
pager.setAdapter(adapter);
return view;
}
}
This is the very simple MyFragmentPagerAdapter,
I put only the getItem() method, and nullPointer checks:
#Override
public Fragment getItem(int position) {
return MySimpleFragment.newInstance(images[position]);
}
And finally SimpleFragment:
public class SimpleFragment extends Fragment{
int id;
public static SimpleAchFragment newInstance(int imgId){
SimpleFragment f = new SimpleFragment();
Bundle args = new Bundle();
args.putLong(ID_BUNDLE, imgId);
f.setArguments(args);
return f;
}
public SimpleAchFragment(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.id = getArguments() != null ? getArguments().getInt(ID_BUNDLE) : 0;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.simple_fragment, container, false);
FragmentActivity mAct = getActivity();
ImageView img = (ImageView) v.findViewById(R.id.image);
img.setImageDrawable(mAct.getResources().getDrawable(id));
return v;
}
}
More info, if the content passed to the adapter ( an int array with 3 ints) has length zero, then the adapter doesn't try to create any Fragment so dialogs appears correctly but empty (as expected).
The Exception is thrown at SimpleFragment.onCreateView() at the time of inflating.
The id referenced in the exception (as not found) correspond to ViewPager 's id, with is properly defined in R.layout.simple_fragment.
I have try also to build the Dialog with an AlertDialog.builder and also directly with Dialog() contructor, but get the same behaviour.
Try this:
In class AchGalleryDialog
MyFragmentAdapter adapter = new MyFragmentAdapter(getChildFragmentManager(),images);
instead of
MyFragmentAdapter adapter = new MyFragmentAdapter(getFragmentManager(),images);
Because of this:
http://developer.android.com/about/versions/android-4.2.html#NestedFragments
Hope this will help!

Fragment views won't create when ViewGroup is dynamic?

Attempting to use a ViewPager with FragmentPagerAdapter with all dynamic GUI elements (i.e. no XML). Yes I have a good reason and not just because I feel like it :) Cannot find anything in the docs that suggests this should not work.
The only difference between working and not working is having the ViewGroup (LinearLayout) and ViewPager defined in XML as opposed to created in the onCreate(). Gives the following error:
java.lang.IllegalArgumentException: No view found for id 0xffffffff for fragment PageFragment{41936480 #0 id=0xffffffff android:switcher:-1:0}
Code:
public class DynoPagerActivity extends FragmentActivity {
private static class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
return PageFragment.newInstance("My Message " + index);
}
#Override
public int getCount() {
return 4;
}
}
private ViewPager mViewPager;
private MyFragmentPagerAdapter mMyFragmentPagerAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
setContentView(ll);
mViewPager = new ViewPager(this);
mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mMyFragmentPagerAdapter);
ll.addView(mViewPager);
//setContentView(ll); tried here as well...
}
}
and:
public class PageFragment extends Fragment {
public static PageFragment newInstance(String title) {
PageFragment pageFragment = new PageFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
pageFragment.setArguments(bundle);
return pageFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// https://android-review.googlesource.com/#/c/31261/ - bug in Support lib
setUserVisibleHint(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView textView = new TextView(container.getContext());
textView.setText(getArguments().getString("title"));
return textView;
}
}
Seems to be an issue with how/when fragments are created, but failing to find the connection...
The ViewPager results in a call to findViewById() for each "page" which tries to get the parent (the ViewPager ID), which always fails for Views that do not have their ID set. When you programmatically create Views, they get an ID of -1, which after browsing the Android platform source code, always returns null/fail for findViewByID().
Adding an ID makes it work, but then you need to manage IDs yourself safely to avoid issues. Add this to code above to make it work in the onCreate() method:
mViewPager.setId(888889);

Categories

Resources