I want to create a common search for different websites at same time.So I imported text of an EditText from an activity to Fragment activity.Now how to import that text to a fragment?
FragmentActivity:
public class MyActivity6 extends FragmentActivity {
TextView mTextview;
ViewPager viewPager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_activity6);
viewPager = (ViewPager) findViewById(R.id.pager);
FragmentManager fragmentManager = getSupportFragmentManager();
viewPager.setAdapter(new MyAdapter(fragmentManager));
mTextview = (TextView)findViewById(R.id.textView8);
mTextview.setText(getIntent().getStringExtra("mytext"));
}
class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
if (i == 0) {
fragment = new FragmentA();
}
if (i == 1) {
fragment = new FragmentB();
}
if (i == 2) {
fragment = new FragmentC();
}
if (i == 3) {
fragment = new FragmentD();
}
return fragment;
}
#Override
public int getCount() {
return 4;
}
public CharSequence getPageTitle(int position) {
String title = new String();
if (position == 0) {
return "Flipkart";
}
if (position == 1) {
return "Amazon";
}
if (position == 2) {
return "Snapdeal";
}
if (position == 3) {
return "Ebay";
}
return null;
}
}
Fragment :
`
public class FragmentA extends Fragment {
TextView mText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View mainView = (View)
inflater.inflate(R.layout.fragment1, container, false);
WebView webView = (WebView)
mainView.findViewById(R.id.webView12);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.getAllowContentAccess();
webSettings.getDatabaseEnabled();
webSettings.getAllowFileAccess();
webSettings.getCacheMode();
webView.loadUrl("http://m.flipkart.com/search?q=");
webView.setWebViewClient(new WebViewClient());
// Set up the ViewPager with the sections adapter.
webView.setWebViewClient(new MyWebViewClient());
return mainView;}
}
Rather than use the default constructor for your Fragment, follow this common pattern of using a static newInstance() method to pass arguments. Stash these into the arguments bundle then pull them out in the Fragment during its onCreateView() (or wherever you actually need it.)
public class MyFragment extends Fragment {
...
private static final String ARG_TEXT = "_arg_text";
...
public static MyFragment newInstance(String myText) {
Bundle args = new Bundle();
args.putString(ARG_TEXT, myText);
MyFragment ret = new MyFragment();
ret.setArguments(args);
return;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View mainView = (View)
inflater.inflate(R.layout.fragment1, container, false);
Bundle args = getArguments();
String text = args.getString(ARG_TEXT);
// Now use the text however you'd lik
...
}
}
Related
I have a viewPager activity that makes multiple fragments with custom FragmentPagerAdapter.
I need to get the List<Audio> audioList and use it in my fragment.
Here is a small part of my MainActivity where I make the fragments. I do not think the rest of the MainActivity code is required in order to answer this question.
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
PagerAdapter pagerAdapter =
new PagerAdapter(getSupportFragmentManager(), MainActivity.this, audioList);
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
// Iterate over all tabs and set the custom view
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
Here is my custom FragmentPagerAdapter:
public class PagerAdapter extends FragmentPagerAdapter {
String tabTitles[] = new String[] { "Recommended", "Popular", "Rock", "Pop", "Blues", "Chill" };
Context context;
private List<Audio> audioList;
public PagerAdapter(FragmentManager fm, Context context, List<Audio> audioList) {
super(fm);
this.context = context;
this.audioList = audioList;
}
#Override
public int getCount() {
return tabTitles.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new BlankFragment();
case 1:
return new BlankFragment();
case 2:
return new BlankFragment();
case 3:
return new BlankFragment();
case 4:
return new BlankFragment();
case 5:
return new BlankFragment();
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
public View getTabView(int position) {
View tab = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) tab.findViewById(R.id.custom_text);
tv.setText(tabTitles[position]);
return tab;
}
}
And I need to get the List<Audio> audioList into my Fragment here:
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.content_view, container, false);
//Get auidoList here
return rootView;
}
I also need to get the title of the tab in the future but my guess is that I would get it similarly to the audioList. If it is not then I could also use help on getting the tab title.
Additionally if the code style is wrong then I am always happy to have some feedback on it aswell.
The traditional way of doing this is by having an instance method that moves it all via a bundle.
Like this:
public class BlankFragment extends Fragment {
public static BlankFragment newInstance(String title, ArrayList<Audio> audioList) {
BlankFragment blankFragment = new BlankFragment();
Bundle bundle = new Bundle();
bundle.putString("Title", title);
bundle.putParcelableArrayList("AudioList", audioList);
blankFragment.setArguments(bundle);
return blankFragment;
}
public BlankFragment() {
// Required empty public constructor
}
private String title;
private ArrayList<Audio> audioList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null) {
title = bundle.getString("Title");
audioList = getArguments().getParcelableArrayList("AudioList");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.content_view, container, false);
//Get auidoList here
return rootView;
}
}
Obviously your Audio class will need to implement parcelable for this to work. I found a great plugin (Android Parcelable Code Generator) in Android Studio for generating parcelable code that makes that quick and easy.
I am working on a card swipe and card flip functionality and I am using ViewPager and fragments.
My problem is I am not able to update TextView inside fragments as I swipe the card from left to right or right to left but when I flip the card it update the UI.
I tried everything which is available over Internet but none of the soltuion is working for me.
I am following this link https://github.com/jamesmccann/android-view-pager-cards
Here is my code
public class CardContainerFragment extends Fragment {
private boolean cardFlipped = false;
static TextView textview;
public CardContainerFragment() {
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card_container, container, false);
LinearLayout ll = (LinearLayout)rootView.findViewById(R.id.layout);
rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flipCard();
}
});
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment())
.commit();
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
return rootView;
}
final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
int page = CardActivity.mViewPager.getCurrentItem();
int page_index = page+1;
String current_page = page_index + " of " + card_activity.deck_map.size();
CardActivity.tv.setText(current_page);
super.handleMessage(msg);
}
};
public void flipCard() {
Fragment newFragment = null;
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
if (cardFlipped) {
newFragment = new CardFrontFragment();
} else {
newFragment = new CardBackFragment();
}
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, newFragment)
.commit();
cardFlipped = !cardFlipped;
}
public static class CardFrontFragment extends Fragment {
public CardFrontFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card, container, false);
textview = (TextView)rootView.findViewById(R.id.card_front);
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
String complete_text = card_front_string +" \n \n + \n Tap now to flip this card.";
textview.setText(complete_text);
return rootView;
}
}
public static class CardBackFragment extends Fragment {
public CardBackFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card_back, container, false);
TextView textview = (TextView)rootView.findViewById(R.id.card_back);
textview.setMovementMethod(new ScrollingMovementMethod());
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
String deck_data = card_activity.deck_map.get(card_front_string);
textview.setText(deck_data);
return rootView;
}
}
Here is my adapter code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.card_example);
tv = (TextView)findViewById(R.id.tv_card_number);
tv1 = (TextView)findViewById(R.id.tv_card_index);
FragmentManager m = getFragmentManager();
CardPagerAdapter adapter = new CardPagerAdapter(m);
index = getIntent().getStringExtra("index");
card_activity.cardCounter = Integer.parseInt(index);
int count = card_activity.cardCounter;
int final_count = count+1;
String current_page = final_count+" of "+card_activity.deck_map.size();
//CardActivity.tv.setText(current_page);
mViewPager = (ViewPager) findViewById(R.id.view_pager);
// mViewPager.setAllowedSwipeDirection(CustomViewPager.SwipeDirection.all);
mViewPager.setAdapter(adapter);
mViewPager.setCurrentItem(card_activity.cardCounter);
//mViewPager.setOffscreenPageLimit(1);
//mViewPager.setOnPageChangeListener(new pagechangelistener())
//Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
}catch(Exception e){
e.printStackTrace();
}
}
public class CardPagerAdapter extends android.support.v13.app.FragmentStatePagerAdapter {
public CardPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
mViewPager.setOffscreenPageLimit(0);
int page = mViewPager.getCurrentItem();
int page_index = page+1;
String current_page = " of " + card_activity.deck_map.size();
tv.setText(current_page);
tv1.setText(String.valueOf(page_index));
CardContainerFragment cardContainerFragment = new CardContainerFragment();
cardContainerFragment.current_index_front = page;
cardContainerFragment.current_index_back = page;
String card_front_string = card_activity.arraylst.get(page);
CardContainerFragment.complete_text_front = card_front_string +" \n \n + \n Tap now to flip this card.";
Bundle b = new Bundle();
b.putInt("index",page);
CardContainerFragment.complete_text_back = card_activity.deck_map.get(card_front_string);
cardContainerFragment.setArguments(b);
return cardContainerFragment;
}
#Override
public int getCount() {
int len = card_activity.deck_map.size();
return len;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Please let me know what I am doing wrong here.
Thanks in advance
Finally I am able to do this with some efforts.
After searching, I get to know that getItems (The method in CardPagerAdapter) is called two times because Android creates one extra fragments for smooth transition and I was sending or getting wrong position of fragments from getItems.
By letting the android to create one extra fragment and by sending correct position I am able to solve this issue.
Here is my updated code
public class CardActivity extends android.support.v4.app.FragmentActivity {
public TextView tv;
public static String index=null;
public static ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.card_example);
tv = (TextView)findViewById(R.id.tv_card_number);
FragmentManager m = getFragmentManager();
CardPagerAdapter adapter = new CardPagerAdapter(m);
index = getIntent().getStringExtra("index");
card_activity.cardCounter = Integer.parseInt(index);
int count = card_activity.cardCounter;
int final_count = count+1;
String current_page = final_count+" of "+card_activity.deck_map.size();
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(adapter);
mViewPager.setCurrentItem(card_activity.cardCounter);
String current_page_temp =final_count+" of " + card_activity.deck_map.size();
tv.setText(current_page_temp);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Log.e("aaa",position+"");
String current_page = position+1 + " of " + card_activity.deck_map.size();
tv.setText(current_page);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}catch(Exception e){
e.printStackTrace();
}
}
public class CardPagerAdapter extends android.support.v13.app.FragmentStatePagerAdapter {
public CardPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
CardContainerFragment cardContainerFragment = new CardContainerFragment();
Bundle b = new Bundle();
b.putInt("index",i);
cardContainerFragment.setArguments(b);
return cardContainerFragment;
}
#Override
public int getCount() {
int len = card_activity.deck_map.size();
return len;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
}
==================================================================
public class CardContainerFragment extends Fragment {
private boolean cardFlipped = false;
int current_index=0;
static int pos = 0;
public CardContainerFragment() {
/*setHasOptionsMenu(true);*/
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card_container, container, false);
LinearLayout ll = (LinearLayout)rootView.findViewById(R.id.layout);
rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flipCard();
}
});
pos = getArguments().getInt("index");
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment().newInstance(pos))
.commit();
card_activity.tempCounter = card_activity.tempCounter+1;
return rootView;
}
public void flipCard() {
Fragment newFragment = null;
CardFrontFragment cardFrontFragment = null;
CardBackFragment cardBackFragment = null;
if (cardFlipped) {
newFragment = CardFrontFragment.newInstance(CardActivity.mViewPager.getCurrentItem());
} else {
newFragment = cardBackFragment.newInstance(CardActivity.mViewPager.getCurrentItem());
}
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, newFragment)
.commit();
cardFlipped = !cardFlipped;
}
public static class CardBackFragment extends Fragment {
public CardBackFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView_back = inflater.inflate(R.layout.fragment_card_back, container, false);
TextView textview_back = (TextView)rootView_back.findViewById(R.id.card_back);
textview_back.setMovementMethod(new ScrollingMovementMethod());
String text = getArguments().getString("back_text");
textview_back.setText(text);
return rootView_back;
}
static CardBackFragment newInstance(int position) {
CardBackFragment cardBackFragment = new CardBackFragment();
Bundle args = new Bundle();
String card_front_string = card_activity.arraylst.get(position);
String text = card_activity.deck_map.get(card_front_string);
args.putString("back_text", text);
cardBackFragment.setArguments(args);
return cardBackFragment;
}
}
public static class CardFrontFragment extends Fragment {
public CardFrontFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView_front = null;
rootView_front = inflater.inflate(R.layout.fragment_card, container, false);
TextView textview_front = (TextView)rootView_front.findViewById(R.id.card_front);
String text = getArguments().getString("front_text");
textview_front.setText(text);
return rootView_front;
}
static CardFrontFragment newInstance(int position) {
CardFrontFragment cardFrontFragment = new CardFrontFragment();
Bundle args = new Bundle();
String card_front_string = card_activity.arraylst.get(position);
String text = card_front_string +" \n \n + \n Tap now to flip this card.";
args.putString("front_text", text);
cardFrontFragment.setArguments(args);
return cardFrontFragment;
}
}
}
As #david-rawson says
Don't use static fields CardActivity.mViewPager. See https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
Reason for this is that the ViewPager might/will create the views of your fragments before they are displayed to ensure you get that smooth animation that people love ViewPagers for. So the mViewPager calls a number of fragments createView() function at the same time, and at that time the mViewPager has an index for .getCurrentItem() which goes to the CardContainer on the page being viewed.
A better option would be for you to pass CardContainerFragment a String argument with the value for "completeText" which you want it to display whenever it creates either CardBackFragment or CardFrontFragment.
Go through this for more details.
You just have to set data to text view which is used in CardFrontFragment.
Here when ever a swipe happens onCreateView() of CardContainerFragment is called.
You are adding CardFrontFragment every time when onCreateView() is called. you need to use text view of CardFrontFragment instead of using textview of activity.
Just replace CardActivity.tv.setText(current_page);
with textView.setText(current_page);
Make sure the textview you have used in CardFrontFragment is available at class level.
you are using static fragments so textview must be static.
private static TextView textView=null;
Hope this will work for you :)
Have you tried this:
tv.post(new Runnable() {
#Override
public void run() {
CardActivity.tv.setText(current_page);
}
});
I did something similar wihtin my App, and I manage the display of my TextView into the OnCreateView, with a switch case.
I tried to implent your code but did not have all your materials (like custom animator).
You should then try something like that:
public class CardContainerFragment extends AppCompatActivity {
private boolean cardFlipped = false;
static TextView textview;
/*public CardContainerFragment() {
setHasOptionsMenu(true);
}*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity_name);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
/*
The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
// This method will be invoked when a new page becomes selected.
#Override
flipCard();
#Override
public void onPageSelected(int position) {
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state) {
// Code goes here
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_welcome, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Initializing data
Context context = getContext();
View rootView = inflater.inflate(R.layout.fragment_card, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.txtView);
int fragment = getArguments().getInt(ARG_SECTION_NUMBER);
switch (fragment)
{
case 1: //front card
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
String complete_text = card_front_string +" \n \n + \n Tap now to flip this card.";
textview.setText(complete_text);
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment())
.commit();
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
return rootView;
case 2: //back card
TextView textview = (TextView)rootView.findViewById(R.id.card_back);
textview.setMovementMethod(new ScrollingMovementMethod());
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
String deck_data = card_activity.deck_map.get(card_front_string);
textview.setText(deck_data);
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment())
.commit();
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
return rootView;
default:
return rootView;
}
}
}
final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
int page = CardActivity.mViewPager.getCurrentItem();
int page_index = page+1;
String current_page = page_index + " of " + card_activity.deck_map.size();
CardActivity.tv.setText(current_page);
super.handleMessage(msg);
}
};
public void flipCard() {
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, newFragment)
.commit();
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#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);
}
#Override
public int getCount() {
// Show 2 total pages.
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
}
return null;
}
}
The textView is displayed on your page, and when selecting the change, the content of your textview will be changed.
I want to want to make ViewPager with each tab containing three fragments. FragmentPagerAdapter only works for one fragment, so I tried my best to make my own custom adapter extending PagerAdapter. Unfortunately, the code I wrote only displays these three Fragments in the first tab and after restarting the app all tabs are blank. I suspect that it has something to do with onSaveInstanceState, but I don't know how to make it properly. Also, I've read that I shouldn't add the fragments to FragmentTransaction in instantiateItem, but I don't know where else I could do it. Could you help me ?
TaskListPagerActivity:
public class TaskListPagerActivity extends AppCompatActivity implements BottomPanelFragment.OnBottomPanelSelectedListener {
private static final String TAG = "TaskListPagerActivity";
private ViewPager mViewPager;
FragmentStacker[] mStacker;
public static Intent newInstance(Context packageContext) {
Intent intent = new Intent(packageContext, TaskListPagerActivity.class);
return intent;
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_list_pager);
mStacker = new FragmentStacker[7];
mViewPager = (ViewPager) findViewById(R.id.activity_task_list_pager);
mViewPager.setAdapter(new TaskListPagerAdapter(this));
}
// Interface methods
private class TaskListPagerAdapter extends PagerAdapter {
private FragmentActivity mContext;
public TaskListPagerAdapter(FragmentActivity context) {
mContext = context;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment res;
FragmentManager fm = mContext.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (mStacker[position] == null) {
mStacker[position] = new FragmentStacker();
ft.add(container.getId(), mStacker[position]);
} else {
ft.attach(mStacker[position]);
}
res = mStacker[position];
ft.commit();
return res;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
#Override
public int getCount() {
return 7;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView()==view;
}
}}
FragmentStacker:
public class FragmentStacker extends Fragment {
Fragment[] fragments = createFragments();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.task_list_activity_fragment, container, false);
FragmentManager fm = getFragmentManager();
Fragment customDateFragment = fm.findFragmentById(R.id.custom_date_fragment_container);
Fragment taskListFragment = fm.findFragmentById(R.id.task_list_fragment_container);
Fragment bottomPanelFragment = fm.findFragmentById(R.id.bottom_panel_container);
FragmentTransaction fragmentTransaction = fm.beginTransaction();
if (customDateFragment == null) {
customDateFragment = fragments[0];
taskListFragment = fragments[1];
bottomPanelFragment = fragments[2];
fragmentTransaction.add(R.id.custom_date_fragment_container, customDateFragment);
fragmentTransaction.add(R.id.task_list_fragment_container, taskListFragment);
fragmentTransaction.add(R.id.bottom_panel_container, bottomPanelFragment);
fragmentTransaction.commit();
} else {
fragmentTransaction.attach(customDateFragment);
fragmentTransaction.attach(taskListFragment);
fragmentTransaction.attach(bottomPanelFragment);
}
return v;
}
private Fragment[] createFragments() {
return new Fragment[]{new CustomDateFragment(), new TaskListFragment(), new BottomPanelFragment()};
}}
I have a fragment with a ViewPager inside it. In the ViewPager I have 4 content screens so swipe around in. The content has a few TextView components and I'm trying to access them from the first fragment, however when I go to use setText or similar I get a null pointer exception. Ive checked and the id for the TextView is valid, and I've done a clean build.
Here is a snippet of my relevant code:
private TextView textViewOne;
private PagerAdapter mPagerAdapter;
private ViewPager pager;
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_layout_viewpager, container, false);
InitializePaging();
textViewOne = (TextView) rootView.findViewById(R.id.create_name);
//would return null if I did this:
textViewOne.setText("test");
return rootView;
}
private void InitializePaging() {
mPagerAdapter = new ViewPagerAdapter(getContext(), getChildFragmentManager(),
Arrays.asList(PageOne.class, PageTwo.class, PageThree.class, PageFour.class));
pager = (ViewPager) rootView.findViewById(R.id.content_pager);
pager.setAdapter(mPagerAdapter);
}
The PageOne class:
public class PageOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(container == null) {
return null;
}
return (LinearLayout) inflater.inflate(R.layout.fragment_page_one, container, false);
}
}
This is the fragment_layout_viewpager xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/content_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
You are inflating fragment_layout_viewpager, so the create_name should exist in that layout, otherwise it will throw a null pointer.
Create an interface with 1 abstract method. Let the Fragment implement the interface and call the callback method from Activity.In the below example, I try to pass value on click of button from MainActivity to ThirdFragment.
public interface FragmentCommunicator {
public void passDataToFragment(String someValue);
}
public class MainActivity extends FragmentActivity {
FragmentCommunicator fragmentCommunicator;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn= (Button)findViewById(R.id.button) ;
btnsetOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
randomvalue= getRansomString();
if(fragmentCommunicator!=null)
fragmentCommunicator.passDataToFragment(randomvalue);
}
});
ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return FirstFragment.newInstance("FirstFragment, Instance 1");
case 1: return ThirdFragment.newInstance("ThirdFragment, Instance 1");
default: return FirstFragment.newInstance("FirstFragment,Instance 1");
}
}
#Override
public int getCount() {
return 2;
}
}
public static class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_frag, container, false);
TextView tv = (TextView) v.findViewById(R.id.tvFragFirst);
tv.setText(getArguments().getString("msg"));
return v;
}
public static FirstFragment newInstance(String text) {
Log.e("FirstFragment","newInstance called");
FirstFragment f = new FirstFragment();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}
}
public class ThirdFragment extends Fragment implements FragmentCommunicator {
TextView tv;
String value="";
public FragmentCommunicator fragmentCommunicator;
#Override
public void passDataToFragment(String someValue) {
this.value = someValue;
tv.setText(value);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
((MainActivity)activity).fragmentCommunicator = this;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement FragmentCommunicator");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_frag, container, false);
value=getArguments().getString("msg");
tv = (TextView) v.findViewById(R.id.tvFragFirst);
tv.setText(value);
return v;
}
public static ThirdFragment newInstance(String text) {
ThirdFragment f = new ThirdFragment();
Bundle b = new Bundle();
b.putString("msg",text);
f.setArguments(b);
return f;
}
}
I'm using FragmentPagerAdapter with FragmentActivity to create swipe-able Fragments.
My first fragment in that pagerAdapter look like this.
public class MySummaryFragment extends CommonFragment implements OnPageChangeListener
{
private Context mContext;
private View mMyView;
LinearLayout mDetailLayout;
TextView mDateTxtView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
System.out.println("onCreateView() Market summary");
mMyView = inflater.inflate(R.layout.my_page_summary_fragment_layout, container,false);
mDetailLayout = (LinearLayout)mMyView.findViewById(R.id.SummaryDetailLayout);
mDateTxtView = (TextView) mMyView.findViewById(R.id.txtDate);
Account_Id = AccountDetails.getInstance(mContext).getClientCodes().get(0);
sendRequest(Account_Id);
return mMyView;
}
#Override
public void onPageSelected(int arg0) {
System.out.println("inside onPageScrollStateChanged()");
System.out.println("mMyView is null ? = "+(mMyView==null));
mDateTxtView = (TextView) mMyView.findViewById(R.id.txtMarketSummaryDate);
Account_Id = AccountDetails.getInstance(mContext).getClientCodes().get(0);
mDateTxtView.setText("");
sendRequest(Account_Id);
}
}
The problem here is I'm getting NullPointerException when swipe-out to 5-6 fragments and swiping back to first fragment.
When I try to debug, I found that
mMyView is null ? = true
Why so?
Please help me.
Here is my Fragment contains the FragmentPagerAdapter,
public class MyPageDetailViewFragment extends CommonFragment {
private View mView;
Context mContext;
OnPageChangeListener pageChangeListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.my_page_fragments, null);
mContext = getActivity();
setHasOptionsMenu(false);
setupSearchBarComponent();
PagerTabStrip pagerTabStrip = (PagerTabStrip)mView. findViewById(R.id.pager_title_strip);
pagerTabStrip.setDrawFullUnderline(true);
pagerTabStrip.setTabIndicatorColor(Color.BLACK);
/** Getting a reference to the ViewPager defined the layout file */
ViewPager pager = (ViewPager) mView.findViewById(R.id.pager);
/** Getting fragment manager */
FragmentManager fm = ((HomeScreenActivity)mContext).getSupportFragmentManager();
/** Instantiating FragmentPagerAdapter */
final MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm);
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(0);
pageChangeListener = new OnPageChangeListener() {
#Override
public void onPageSelected(int selectedIndex) {
System.out.println("selectedIndex = "+selectedIndex);
Object page = pagerAdapter.getItem(selectedIndex);
if( page instanceof OnPageChangeListener){
((OnPageChangeListener) page).onPageSelected(selectedIndex);
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
};
pager.setOnPageChangeListener(pageChangeListener);
return mView;
// return super.onCreateView(inflater, container, savedInstanceState);
}
And here is my implementation MyFragmentPagerAdapter,
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
/** Constructor of the class */
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
/** This method will be invoked when a page is requested to create */
#Override
public Fragment getItem(int index) {
System.out.println("getItem = "+index);
Bundle data = new Bundle();
data.putInt("current_page", index + 1);
CommonFragment fragment = getFragment(index);
fragment.setArguments(data);
return fragment;
}
public CommonFragment getFragment(int index) {
CommonFragment fragment = null;
if(fragment == null){
if(index == 0){
fragment = new MySummaryFragment();
}else if(index == 1){
fragment = new FragmentOne();
}else if(index == 4){
fragment = new FragmentFour();
}else if(index == 5){
fragment = new FragmentFive();
}else{
fragment = new MyFragment();
}
}
return fragment;
}
/** Returns the number of pages */
#Override
public int getCount() {
return titles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
pagerAdapter.getItem(selectedIndex) actually creates a new instance of the fragment.
See this answer: https://stackoverflow.com/a/23843743/1271907
You have to keep a reference to the actual fragment.
It looks like you are calling the wrong method on the inflater.
Try to change this line:
mView = inflater.inflate(R.layout.my_page_fragments, null);
to:
mView = inflater.inflate(R.layout.my_page_fragments,container, null);