I have two fragments in my activity. I'm implementing actionbarsherlock TabNavigation and each tab has separate fragment. I'm performing network operation and place the results in a TextView.
If I change the fragment after the current fragment is completely loaded, it works fine. The NullPointerException only occurs if I change the fragment while the current fragment is still loading. Please help.
FRAGMENT 1:
public class Fragment1 extends SherlockFragment {
public static Fragment1 newInstance() {
Fragment1 f = new Fragment1 ();
return f;
}
private static LinearLayout mainll;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub4
final View V = inflater.inflate(R.layout.fragment_1, container, false);
AsyncHttpClient client = new AsyncHttpClient();
client.get(((MainActivity) act).getUrl(), new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
Document document = Jsoup.parse(response);
Element results = document.getElementById("search_results");
mainll = (LinearLayout) V.findViewById(R.id.content);
LayoutParams mainllParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mainllParams.setMargins(10, 5, 0, 0);
if(results != null) {
TextView tv= new TextView(getActivity()); //NPE occurs here
tv.setLayoutParams(mainllParams);
tv.setText(results.ownText());
tv.setGravity(Gravity.CENTER_HORIZONTAL);
mainll.addView(tv);
}
});
return V;
}
}
FRAGMENT 2:
public class Fragment2 extends SherlockFragment {
public static Fragment2 newInstance() {
Fragment2 f = new Fragment2 ();
return f;
}
private static LinearLayout mainll;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub4
final View V = inflater.inflate(R.layout.fragment_1, container, false);
AsyncHttpClient client = new AsyncHttpClient();
client.get(((MainActivity) act).getUrl(), new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
Document document = Jsoup.parse(response);
Element results2 = document.getElementById("more_results");
mainll = (LinearLayout) V.findViewById(R.id.content);
LayoutParams mainllParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mainllParams.setMargins(10, 5, 0, 0);
if(results2 != null) {
TextView tv2 = new TextView(getActivity()); //NPE Occurs here
tv2.setLayoutParams(mainllParams);
tv2.setText(results.ownText());
tv2.setGravity(Gravity.CENTER_HORIZONTAL);
mainll.addView(tv2);
}
});
return V;
}
}
Thanks in advance
Well, you already answered your own question: NPE occurs because current fragment is in detached state, it's mean it detached from activity and have no link to it -> getActivity() returns null.
You could add several extra options for your check to verify that your fragment is still visible and attached:
if(results2 != null && getActivity()!=null && isVisible()) {
TextView tv2 = new TextView(getActivity()); //NPE Occurs here
tv2.setLayoutParams(mainllParams);
tv2.setText(results.ownText());
tv2.setGravity(Gravity.CENTER_HORIZONTAL);
mainll.addView(tv2);
}
Related
UPDATE: This is my current code, however it breaks after I re-click the same button....
Cause: java.lang.IllegalStateException: Fragment already active
I have a main_activity.xml split into Frame layouts.
The upper frame layout contains an edit text and 3 buttons (small, medium, large).
The lower frame layout contains a text view to populate the text of the edit text in either small, medium or large font.
I put the text into a bundle and am attempting to reopen that bundle in the corresponding fragment once the button is clicked.... however, the bundle does not contain any text information from the text according to my debugger.
Here is my code with the medium, large buttons removed
Any help, please?
MainActivity:
public class MainActivity extends AppCompatActivity {
TextView textView;
Button bSmall;
Small fSmall = new Small();
Bundle bundle = new Bundle();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(findViewById(R.id.fragment)!=null){
if(savedInstanceState!=null){
return;
}
}
final EditText editText = (EditText) findViewById(R.id.type_here);
final Button bSmall = (Button)findViewById(R.id.small);
Button bMedium = (Button)findViewById(R.id.medium);
bSmall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message_small = editText.getText().toString();
small = message_small;
bundle.putString("message_small", message_small);
fSmall.setArguments(bundle);
FragmentManager fm =getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment, fSmall).commit();
}
});
bMedium.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message_medium = editText.getText().toString();
bundle.putString("message_medium", message_medium);
fMedium.setArguments(bundle);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment, fMedium).commit();
}
});
}
public String getMyData(){
return small;
}
}
Small:
public class Small extends Fragment {
EditText editText;
View myView;
public Small() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.fragment_small, container, false);
Bundle bundle = new Bundle();
bundle = getArguments();
MainActivity activity = (MainActivity)getActivity();
//String dataFromMainActivity = activity.getMyData();
String myString = bundle.getString("message_small");
TextView set = myView.findViewById(R.id.small_text);
set.setText(myString);
// Inflate the layout for this fragment
return myView;
}
}
You forgot to add the bundle to the fragment.
You need to do something like this:
Small fSmall = new Small();
...
bundle.putString("message_small", message_small);
fSmall.setArguments(bundle);
FragmentManager fm =getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment, fSmall);
I think you forgot to add your bundle to your Fragment before calling the fragment manager.
You should try something like this:
Small fSmall = new Small();
Bundle bundle = new Bundle();
bundle.putString("message_small", message_small); //parameters are (key, value).
fSmall.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, fSmall).commit();
In your second fragment, you should check if myString is not null or empty.
String myString = getArguments().getString("message_small");
if (myString == null) {
Log.e("TAG", "Error: null argument");
}
EDIT I see another problem here. You are accessing varaibles that have not been instatiated. You should inflate your layout before calling findViewById() or it will return a NullPointerException.
Update your Small class like this :
public class Small extends Fragment {
private EditText editText;
View myView;
public Small() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
myView = inflater.inflate(R.layout.fragment_small, container, false);
String myString = getArguments().getString("message_small");
// Here, myView is != null
TextView editText = myView.findViewById(R.id.small_text);
// Here, editText is != null
editText.setText(myString);
return myView;
}
}
Best
I had a fragment, in which first I check for availability for internet connection. If its available its fine, otherwise, I want to refresh the page by clicking on retry button. The problem which comes is, I am not able to refresh the fragment
This is my fragment code.
public View onCreateView(LayoutInflater inflater, #Nullable final ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.homework, container, false);
listView = rootView.findViewById(R.id.home_list);
adapter = new HomeWorkAdapter(getContext(), R.layout.home_single, arrayList);
listView.setAdapter(adapter);
cal = rootView.findViewById(R.id.date_select);
boolean x = handleNetworkConnection();
if (x == true) {
methodListener();
SharedPreferences preferences = getActivity().getSharedPreferences("user_login", Context.MODE_PRIVATE);
HashMap<String, String> map = new HashMap<>();
map.put("school_id", preferences.getString("school_id", ""));
map.put("class", preferences.getString("classes", ""));
map.put("sec", "homeera");
defaultfetch(map);
}
else
{
final LinearLayout ll = new LinearLayout(getActivity());
TextView textView = new TextView(getActivity());
Button button = new Button(getActivity());
ImageView image = new ImageView(getActivity());
ll.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
ll.setBackgroundColor(Color.parseColor("#ecf0f1"));
image.setImageResource(R.drawable.errorsq);
button.setBackgroundColor(Color.parseColor("#02b48a"));
button.setText("Try Again");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/*
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(getActivity().).attach(this).commit();
*/
}
});
ll.addView(textView);
ll.addView(image);
ll.addView(button);
ll.setOrientation(LinearLayout.VERTICAL);
View rootview = ll;
return rootview;
}
return rootView;
}
In this code, I had applied a way to refresh the fragment, but the problem is that after refreshing UI comes blank. Nothing is there on the screen.
You should not refresh the fragment but refresh the list when you get an internet connection.
Since your method handleNetworkConnection() returns synchronously, you could organize the code as follows:
public View onCreateView(LayoutInflater inflater, #Nullable final ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.homework, container, false);
listView = rootView.findViewById(R.id.home_list);
adapter = new HomeWorkAdapter(getContext(), R.layout.home_single, arrayList);
listView.setAdapter(adapter);
cal = rootView.findViewById(R.id.date_select);
prepareList();
}
void prepareList() {
boolean x = handleNetworkConnection();
if (x == true) {
// same code as now, load the list content and display it
} else {
// same code as now except the click listener:
public void onClick(View view) {
prepareList();
}
//
}
}
I want to dynamically add text views in my app depending on the information I receive from the database. I am taking a reference to the linear layout and then instantiating text views in a loop, setting LayoutParams to them and then adding them to the the layout all this is done inside a static inner fragment class. I have gone through almost every solution and I am doing the same thing as others did but when I run my app on device I don't see the dynamically added views. Please help me solve this issue.
Here is a copy of my code:
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";
final int PICKFILE_RESULT_CODE = 1;
String FilePath="";
UploadFileAsync u;
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) {
View rootView;
// TextView textView = (TextView) rootView.findViewById(R.id.section_label);
// textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
int sectionNumber = getArguments().getInt(ARG_SECTION_NUMBER);
switch (sectionNumber){
case 1: rootView = inflater.inflate(R.layout.fragment_faculty_home_info, container, false);
facultyInfoFragment(rootView);
break;
case 2: rootView = inflater.inflate(R.layout.fragment_faculty_home_exam, container, false);
facultyExamFragment(rootView);
break;
case 3: rootView = inflater.inflate(R.layout.fragment_faculty_home_info, container, false);
facultyEventsFragment(rootView);
break;
default: rootView = inflater.inflate(R.layout.fragment_faculty_home_info, container, false);
}
return rootView;
}
public void facultyInfoFragment(View rootView){
TextView facultyInfoName = (TextView)rootView.findViewById(R.id.faculty_info_name_view);
facultyInfoName.setText("Ravi Singh");
TextView facultyInfoID = (TextView)rootView.findViewById(R.id.faculty_info_ID_view);
facultyInfoID.setText("12345");
TextView facultyInfoDept = (TextView)rootView.findViewById(R.id.faculty_info_dept_view);
facultyInfoDept.setText("CSE");
Button facultyInfoCaddButton = (Button)rootView.findViewById(R.id.faculty_info_cADD_button);
Button facultyInfoCdeleteButton = (Button)rootView.findViewById(R.id.faculty_info_cDelete_button);
EditText facultyInfoCIDField = (EditText)rootView.findViewById(R.id.faculty_info_cID_field);
EditText facultyInfoCnameField = (EditText)rootView.findViewById(R.id.faculty_info_cname_field);
if (facultyInfoCIDField.getText().toString() != null && facultyInfoCnameField.getText().toString() != null){
facultyInfoCaddButton.setEnabled(true);
facultyInfoCdeleteButton.setEnabled(true);
}
else{
facultyInfoCaddButton.setEnabled(false);
facultyInfoCdeleteButton.setEnabled(false);
}
facultyInfoCaddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
facultyInfoCdeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
// this is the part where I dynamically try to add views
LinearLayout facultyInfoLayout = (LinearLayout)rootView.findViewById(R.id.faculty_info_layout);
int numberOfCourses = super.getArguments().getInt(SignupActivity.courses);// no. of courses returned from database
TextView coursesTextView[] = new TextView[numberOfCourses];
for (int i = 0; i < numberOfCourses; i++){
coursesTextView[i] = new TextView(getContext());
coursesTextView[i].setText("CSE1212 RDBMS"); //enter the course ID and course name returned from database
coursesTextView[i].setLayoutParams(new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
facultyInfoLayout.addView(coursesTextView[i]);
}
return;
}
public void facultyExamFragment(View rootView){
Button uploadExamScheduleButton = (Button)rootView.findViewById(R.id.faculty_exam_upload_button);
uploadExamScheduleButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
startActivityForResult(intent,PICKFILE_RESULT_CODE);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode){
case PICKFILE_RESULT_CODE:
if(resultCode==RESULT_OK){
FilePath = data.getData().getPath();
FilePath=FilePath.split(":")[1];
u=new UploadFileAsync(FilePath);
u.execute("");
}
break;
}
}
public static void facultyEventsFragment(View rootView){
}
}
Set orientation for your parent Linearlayout to which you are adding your textviews.
LinearLayout facultyInfoLayout = (LinearLayout)rootView.findViewById(R.id.faculty_info_layout);
facultyInfoLayout.setOrientation(LinearLayout.VERTICAL);
Remove LinearLayoutCompact instead use only LinearLayout in layout params
coursesTextView[i].setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
This is my xml part
<LinearLayout
android:layout_width="match_parent"
android:id="#+id/parent"
android:layout_height="wrap_content"
android:orientation="vertical">
This is my java part
LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
TextView coursesTextView[] = new TextView[5];
for (int i = 0; i < 5; i++){
coursesTextView[i] = new TextView(this);
coursesTextView[i].setText("CSE1212 RDBMS"); //enter the course ID and course name returned from database
coursesTextView[i].setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
parent.addView(coursesTextView[i]);
}
And this adds 5 textviews one after the other
change this line
coursesTextView[i].setLayoutParams(new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
to . May be that is problem.and also set text color , may be same color not display textview.
tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
tv.setTextColor(mHostActivity.getResources().getColor(R.color.orange));
I have a fragment ArticleFragment which is passed an Article object.
The ArticleFragment is usually displayed in an Activity but I would like to reuse the fragment inside a ListView. Each row of the ListView should hold an instance of ArticleFragment.
I know that I can customize a row with the getView() method of the adapter but the UI displayed by the ArticleFragment is very much alike as that of a row so it would be annoying to have to update it at two positions if the UI changes.
ArticleFragment.java
public class ArticleFragment extends SherlockFragment {
static final String ARTICLE_PARCEL_KEY = "parcelable_article";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected static ArticleFragment newInstance(Article article) {
ArticleFragment f = new ArticleFragment();
Bundle args = new Bundle(Article.class.getClassLoader());
args.putParcelable(ARTICLE_PARCEL_KEY, article);
f.setArguments(args);
return f;
}
Article getArticle() {
return getArguments().getParcelable(ARTICLE_PARCEL_KEY);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = (View) inflater.inflate(R.layout.article, container, false);
ArticleImagesFragment imagesFragment = ArticleImagesFragment.newInstance(getArticle().getImages());
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
ft.add(R.id.images_fragment_container, imagesFragment);
if (getActivity() instanceof ArticleActivity) {
DisqusCommentsFragment disqusFragment = DisqusCommentsFragment.newInstance(getArticle().getCommentsUrl());
ft.add(R.id.comments_fragment_container, disqusFragment);
}
ft.commit();
return layout;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Article article = getArticle();
TextView kickerView = (TextView) view.findViewById(R.id.kicker);
kickerView.setText(article.getKicker().toUpperCase());
TextView titleView = (TextView) view.findViewById(R.id.title);
titleView.setText(article.getTitle());
String commentsText = "Jetzt kommentieren!";
if (article.getNumComments() == 1) {
commentsText = article.getNumComments().toString() + " Kommentar";
} else if (article.getNumComments() > 1) {
commentsText = article.getNumComments().toString() + " Kommentare";
}
TextView numCommentsView = (TextView) view.findViewById(R.id.num_comments);
numCommentsView.setText(commentsText);
TextView pubDateView = (TextView) view.findViewById(R.id.pub_date);
String dateText = new SimpleDateFormat("dd. MMMM, hh:mm").format(article.getPubDate());
pubDateView.setText(dateText);
TextView authorNameView = (TextView) view.findViewById(R.id.author_name);
authorNameView.setText(article.getAuthorName());
TextView articleTextView = (TextView) view.findViewById(R.id.text);
articleTextView.setText(Html.fromHtml(article.getHtmlContent()));
}
}
I noticed that it's possible to pass a custom row layout to the ArrayAdapter but that would again duplicate the logic for displaying the UI of an Article. Instead I would prefer to pass a fragment to the constructor of the adapter and use it to display the row.
Is it possible to achieve this with an ArrayAdapter?
If not what would be the right path to take to achieve the reuse of the ArticleFragment in a ListView?
Thanks for your help!
I have a ViewPager with three Fragments, each one shows a List (or Grid).
In the new Android API level 17 (Jelly Bean 4.2), one of the features is Nested Fragments. The new functionality description says:
if you use ViewPager to create fragments that swipe left and right and
consume a majority of the screen space, you can now insert fragments
into each fragment page.
So, if I understand right, now I can create a ViewPager with Fragments (with a button inside for example) inside, and when user press the button show another Fragment without loose the ViewPager using this new feature.
I've expended my morning trying to implement this several different ways, but I canĀ“t get it working... Can somebody add a simple example of how to implement this?
PS: I'm only interested in doing at this way, with getChildFragmentManager to learn how works.
Assuming you have created the correct xml layouts. It is now very simple to display fragments in a ViewPager that is hosted by another Fragment.
The following is a parent fragment that displays child fragments:
class ParentViewPagerFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val root = inflater.inflate(R.layout.fragment_parent_viewpager, container, false)
val viewPager = root.findViewById(R.id.viewPager) as ViewPager
// Important: Must use the child FragmentManager or you will see side effects.
viewPager.adapter = MyAdapter(childFragmentManager)
val tabStrip = root.findViewById<TabLayout>(R.id.pagerTabStrip)
tabStrip.setupWithViewPager(viewPager)
return root
}
class MyAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getCount(): Int = 4
override fun getItem(position: Int): Fragment {
val args = Bundle().apply { putInt(ChildFragment.POSITION_KEY, position) }
return ChildFragment.newInstance(args)
}
override fun getPageTitle(position: Int): CharSequence = "Tab $position"
}
companion object {
val TAG: String = ParentViewPagerFragment::class.java.name
}
}
It is important to use Fragment.getChildFragmentManager() when instantiating the FragmentPagerAdapter. Also note that you cannot use Fragment.setRetainInstance() on the children fragments or you'll get an exception. The imports were omitted for brevity.
Source code can be found at: https://github.com/marcoRS/nested-fragments
Edit:
If you want to replace all the content of a page in a ViewPager you could still use nested fragments, but some changes are needed. Check the sample below(the FragmentActivity, setting the ViewPager and the PagerAdapter are the same as the previous snippet of code):
// this will act as a fragment container, representing one page in the ViewPager
public static class WrapperFragment extends Fragment implements
ReplaceListener {
public static WrapperFragment newInstance(int position) {
WrapperFragment wp = new WrapperFragment();
Bundle args = new Bundle();
args.putInt("position", position);
wp.setArguments(args);
return wp;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FrameLayout fl = new FrameLayout(getActivity());
fl.setId(10000);
if (getChildFragmentManager().findFragmentByTag("initialTag") == null) {
InitialInnerFragment iif = new InitialInnerFragment();
Bundle args = new Bundle();
args.putInt("position", getArguments().getInt("position"));
iif.setArguments(args);
getChildFragmentManager().beginTransaction()
.add(10000, iif, "initialTag").commit();
}
return fl;
}
// required because it seems the getChildFragmentManager only "sees"
// containers in the View of the parent Fragment.
#Override
public void onReplace(Bundle args) {
if (getChildFragmentManager().findFragmentByTag("afterTag") == null) {
InnerFragment iif = new InnerFragment();
iif.setArguments(args);
getChildFragmentManager().beginTransaction()
.replace(10000, iif, "afterTag").addToBackStack(null)
.commit();
}
}
}
// the fragment that would initially be in the wrapper fragment
public static class InitialInnerFragment extends Fragment {
private ReplaceListener mListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mListener = (ReplaceListener) this.getParentFragment();
LinearLayout ll = new LinearLayout(getActivity());
Button b = new Button(getActivity());
b.setGravity(Gravity.CENTER_HORIZONTAL);
b.setText("Frame " + getArguments().getInt("position"));
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bundle args = new Bundle();
args.putInt("positionInner",
getArguments().getInt("position"));
if (mListener != null) {
mListener.onReplace(args);
}
}
});
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(b, new LinearLayout.LayoutParams(250,
LinearLayout.LayoutParams.WRAP_CONTENT));
return ll;
}
}
public static class InnerFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView tv = new TextView(getActivity());
tv.setText("InnerFragment in the outher Fragment with position "
+ getArguments().getInt("positionInner"));
return tv;
}
}
public interface ReplaceListener {
void onReplace(Bundle args);
}
At a quick look it works, but issues may appear as I haven't tested it to much.
Can somebody show a simple example of how to do this?
Using nested fragments seems pretty easy, until Commonsware comes with a more elaborated sample you can try the code below:
public class NestedFragments extends FragmentActivity {
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
ViewPager vp = new ViewPager(this);
vp.setId(5000);
vp.setAdapter(new MyAdapter(getSupportFragmentManager()));
setContentView(vp);
}
private static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return WrapperFragment.newInstance(position);
}
#Override
public int getCount() {
return 8;
}
}
public static class WrapperFragment extends Fragment {
public static WrapperFragment newInstance(int position) {
WrapperFragment wp = new WrapperFragment();
Bundle args = new Bundle();
args.putInt("position", position);
wp.setArguments(args);
return wp;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout ll = new LinearLayout(getActivity());
FrameLayout innerFragContainer = new FrameLayout(getActivity());
innerFragContainer.setId(1111);
Button b = new Button(getActivity());
b.setText("Frame " + getArguments().getInt("position"));
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
InnerFragment innerFragment = new InnerFragment();
Bundle args = new Bundle();
args.putInt("positionInner",
getArguments().getInt("position"));
innerFragment.setArguments(args);
FragmentTransaction transaction = getChildFragmentManager()
.beginTransaction();
transaction.add(1111, innerFragment).commit();
}
});
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(b, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
ll.addView(innerFragContainer, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
return ll;
}
}
public static class InnerFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView tv = new TextView(getActivity());
tv.setText("InnerFragment in the outher Fragment with position "
+ getArguments().getInt("positionInner"));
return tv;
}
}
}
I was lazy and made everything in code but I'm sure it can work with inflated xml layouts.
I have created a ViewPager with 3 elements and 2 sub elements for index 2 and 3 and here what I wanted to do..
I have implemented this with the help from previous questions and answers from StackOverFlow and here is the link.
ViewPagerChildFragments
Easily use Navigation Component in your app! then in your listener, copy this code:
findNavController().navigate('Your action Id)
Your action id which IDE created automatically for you.