I have RadioButton and Checkboxes that are added programatically inside Fragments under ViewPager. Here's how I added the RadioButton/Checkboxes.
public class TeaserExam extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//get all the checked values here
}
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#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,questionList.get(position).getId(),
questionList.get(position).getQuestion(),questionList.get(position).getQuestionType(),questionList.get(position).getChoices());
}
}
public static class PlaceholderFragment extends Fragment {
public static PlaceholderFragment newInstance(int number, int questionID, String question, int questionType, List<Choices> choices) {
PlaceholderFragment fragment = new PlaceholderFragment();
ArrayList<Integer> choicesID = new ArrayList<>();
ArrayList<String> choicesLabel = new ArrayList<>();
for (int i = 0; i < choices.size(); i++){
choicesID.add(i,choices.get(i).getId());
choicesLabel.add(i,choices.get(i).getLabel());
}
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, number);
args.putInt("questionID", questionID);
args.putInt("questionType", questionType);
args.putInt("choicesSize", choices.size());
ParcelableChoices parcelableChoices = new ParcelableChoices(choicesID,choicesLabel);
args.putParcelable("parcelableChoices", parcelableChoices);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_teaser_exam, container, false);
int questionID = getArguments().getInt("questionID");
int questionType = getArguments().getInt("questionType");
int choicesSize = getArguments().getInt("choicesSize");
ParcelableChoices parcelableChoices = getArguments().getParcelable("parcelableChoices");
LinearLayout ll_choices = (LinearLayout)rootView.findViewById(R.id.ll_choices);
ArrayList<Integer> choicesIDs = parcelableChoices.getId();
ArrayList<String> choicesLabels = parcelableChoices.getLabel();
if (questionType == 2){
//checkboxes
for (int i = 0; i < choicesSize; i++){
CheckBox myChoices = new CheckBox(getContext());
myChoices.setId(choicesIDs.get(i));
myChoices.setText(choicesLabels.get(i));
myChoices.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
ll_choices.addView(myChoices);
}
}else{
//radio group
RadioGroup rg = new RadioGroup(getContext());
rg.setOrientation(RadioGroup.VERTICAL);
for (int i = 0; i < choicesSize; i++){
RadioButton myChoices = new RadioButton(getContext());
myChoices.setId(choicesIDs.get(i));
myChoices.setText(choicesLabels.get(i));
myChoices.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
rg.addView(myChoices);
}
ll_choices.addView(rg);
}
return rootView;
}
}
}
The problem is right now I have no idea how to retrieve the checked radiobutton/checkboxes value. I want to get all the checked values when I click on a button which will appear only at the last page.
Since all the views are added to ll_choices, is there any way I can get the id and values of all views added under ll_choices?
The direct answer to your question is to keep a reference to the controls which you add programmatically. You can do this with member field variables rather than local variables.
Since you are adding a list of dynamic views, you should learn about ListView or RecyclerView. These are designed for adding dynamic views. I also suggest that you separate the RadioButtons and the CheckBoxes into two separate fragments. Then the activity decides which fragment to show.
Currently your variables are local to onCreate inside the fragment.
Make them class fields inside the fragment class, initialize them inside onCreate and then they will be available inside the whole fragment class
Related
I'm new in android and want an app with viewpager. I am unable to design the viewpager in the layout. The layout fetch the data dynamatically. I want to create a matreial UI viewpager which swipes the page left or right like a paper.I have made a view which shows the data but is unable to swipe like a viewpager left or right...
The code is as below:
public class DetailNewsActivity extends AppCompatActivity {
private PullToZoomScrollViewEx scrollView;
private ArrayList<NewsItemModel> newsArr;
private TextView tvNewsTitle;
private TextView tvNewsPublishDate;
private TextView tvNewsFull;
private int newsPosition = 0;
private ImageView ivYoutubeEnable;
private SharedPreferences sharedPref;
int textSize = 16;
boolean isHighQuality = false;
private Typeface typeface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail_news);
init();
AdView mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice("5745FD6726ACCBEE8324DB158D021FA5")
.build();
mAdView.loadAd(adRequest);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_detail_news, container, false);
return view;
}
private void init() {
typeface = Typeface.createFromAsset(getAssets(), "AnmolUni.ttf");
// newsArr = (ArrayList<NewsItemModel>) getIntent().getSerializableExtra("newsArray");
newsArr = AppController.getAppController().getMainNewsArr();
AppController.getAppController().setMainNewsArr(null);
newsPosition = getIntent().getIntExtra("newsPosition", 0);
findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
findViewById(R.id.iv_share).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
generateBranchURL(newsPosition);
}
});
sharedPref = getSharedPreferences(Constants.SHARED_PREF_NAME, Context.MODE_PRIVATE);
textSize = sharedPref.getInt("text_size", 16);
isHighQuality = sharedPref.getBoolean("isHighQuality",false);
loadViewForCode();
scrollView = (PullToZoomScrollViewEx) findViewById(R.id.scroll_view);
setNewsFromArray(newsPosition);
// ((ImageView) scrollView.getZoomView().findViewById(R.id.iv_zoom)).setImageResource(android.R.drawable.arrow_down_float);
(scrollView.getZoomView().findViewById(R.id.iv_zoom)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(DetailNewsActivity.this, ImageVideoActivity.class);
intent.putExtra("viewType", "image");
if(isHighQuality)
intent.putExtra("imageArr", newsArr.get(newsPosition).getImage());
else
intent.putExtra("imageArr", newsArr.get(newsPosition).getMedium());
startActivity(intent);
}
});
DisplayMetrics localDisplayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);
int mScreenHeight = localDisplayMetrics.heightPixels;
int mScreenWidth = localDisplayMetrics.widthPixels;
LinearLayout.LayoutParams localObject = new LinearLayout.LayoutParams(mScreenWidth, (int) (9.0F * (mScreenWidth / 16.0F)));
scrollView.setHeaderLayoutParams(localObject);
scrollView.setParallax(true);
// scrollView.getPullRootView().findViewById(R.id.container_layout).setOnTouchListener(new OnSwipeTouchListener(DetailNewsActivity.this) {
scrollView.getPullRootView().setOnTouchListener(new OnSwipeTouchListener(DetailNewsActivity.this) {
#Override
public void onSwipeLeft() {
if (newsPosition < newsArr.size() - 1) {
newsPosition++;
setNewsFromArray(newsPosition);
} else {
CommonUtils.showToast(DetailNewsActivity.this, "No more news");
}
}
#Override
public void onSwipeRight() {
if (newsPosition > 0) {
newsPosition--;
setNewsFromArray(newsPosition);
} else {
CommonUtils.showToast(DetailNewsActivity.this, "This is the first news");
}
}
});
scrollView.setOnPullZoomListener(new PullToZoomBase.OnPullZoomListener() {
#Override
public void onPullZooming(int newScrollValue) {
Log.d("MainActivity", "onPullZooming: " + newScrollValue);
// Intent intent = new Intent(DetailNewsActivity.this, ImageVideoActivity.class);
// intent.putExtra("viewType", "image");
// intent.putExtra("imageArr", newsArr.get(newsPosition).getImage());
// startActivity(intent);
}
#Override
public void onPullZoomEnd() {
}
});
}
void setNewsFromArray(int position) {
if (position >= newsArr.size()) {
finish();
return;
}
if (!newsArr.get(position).getMedium().get(0).isEmpty()) {
if(isHighQuality)
Picasso.with(DetailNewsActivity.this).load(newsArr.get(position).getImage().get(0)).placeholder(R.drawable.logo).error(R.drawable.logo).
into((ImageView) scrollView.getZoomView().findViewById(R.id.iv_zoom));
else
Picasso.with(DetailNewsActivity.this).load(newsArr.get(position).getMedium().get(0)).placeholder(R.drawable.logo).error(R.drawable.logo).
into((ImageView) scrollView.getZoomView().findViewById(R.id.iv_zoom));
} else {
((ImageView) scrollView.getZoomView().findViewById(R.id.iv_zoom)).setImageResource(R.drawable.logo);
}
tvNewsTitle.setText(newsArr.get(position).getTitle());
tvNewsPublishDate.setText(newsArr.get(position).getPublish_dt());
//String style = "<html><body style='text-align:justify'>";
//Log.i("RAJEEV",style + newsArr.get(position).getFullnews());
tvNewsFull.setText(Html.fromHtml( newsArr.get(position).getFullnews()));
if (newsArr.get(position).getYoutube_video().isEmpty()) {
ivYoutubeEnable.setVisibility(View.GONE);
} else {
ivYoutubeEnable.setVisibility(View.VISIBLE);
}
ivYoutubeEnable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(DetailNewsActivity.this, ImageVideoActivity.class);
intent.putExtra("viewType", "youtube");
intent.putExtra("youtube_code", newsArr.get(newsPosition).getYoutube_video());
startActivity(intent);
}
});
}
private void loadViewForCode() {
PullToZoomScrollViewEx scrollView = (PullToZoomScrollViewEx) findViewById(R.id.scroll_view);
View headView = LayoutInflater.from(this).inflate(R.layout.ptz_head_view, null, false);
View zoomView = LayoutInflater.from(this).inflate(R.layout.ptz_zoom_view, null, false);
View contentView = LayoutInflater.from(this).inflate(R.layout.ptz_content_view, null, false);
scrollView.setHeaderView(headView);
scrollView.setZoomView(zoomView);
scrollView.setScrollContentView(contentView);
tvNewsTitle = (TextView) scrollView.getPullRootView().findViewById(R.id.tv_news_title);
tvNewsPublishDate = (TextView) scrollView.getPullRootView().findViewById(R.id.tv_news_publish_date);
tvNewsFull = (TextView) scrollView.getPullRootView().findViewById(R.id.tv_news_full);
tvNewsFull.setTextSize(textSize);
if (!AppController.isPunjabiSupported()) {
tvNewsTitle.setTypeface(typeface);
tvNewsFull.setTypeface(typeface);
}
ivYoutubeEnable = (ImageView) scrollView.getHeaderView().findViewById(R.id.iv_youtube_header);
}
void generateBranchURL(final int newsPosition) {
// String imageUrl = "";
// if (newsArr.get(newsPosition).getMedium().size() <= 1)
// imageUrl = newsArr.get(newsPosition).getMedium().get(0);
BranchUniversalObject branchUniversalObject = new BranchUniversalObject()
.setCanonicalIdentifier("NewsDetails")
///.setCanonicalUrl("https://branch.io/deepviews")
//.setTitle("" + newsArr.get(newsPosition).getTitle())
//.setContentDescription("" + newsArr.get(newsPosition).getIntro())
//.setContentImageUrl("" + imageUrl)
// You use this to specify whether this content can be discovered publicly - default is public
.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC);
// Here is where you can add custom keys/values to the deep link data
//.addContentMetadata("property1", "blue")
//.addContentMetadata("property2", "red");
LinkProperties linkProperties = new LinkProperties()
.addControlParameter("$desktop_url", "http://www.newsnumber.com/news/share/" + newsArr.get(newsPosition).getFn_id())
.addControlParameter("$ios_url", "itms-apps://itunes.apple.com/us/app/newsnumber/id1022442357?mt=8")
.addControlParameter("NewsId", "" + newsArr.get(newsPosition).getFn_id())
.addControlParameter("CatId", "" + newsArr.get(newsPosition).getCat_id())
.addControlParameter("$og_title", newsArr.get(newsPosition).getTitle())
.addControlParameter("$og_description", newsArr.get(newsPosition).getIntro())
.addControlParameter("$og_image_url", newsArr.get(newsPosition).getImage().get(0))
.addControlParameter("$twitter_title", newsArr.get(newsPosition).getTitle())
.addControlParameter("$twitter_description", newsArr.get(newsPosition).getIntro())
.addControlParameter("$twitter_image_url", newsArr.get(newsPosition).getImage().get(0))
;
branchUniversalObject.generateShortUrl(this, linkProperties, new Branch.BranchLinkCreateListener() {
#Override
public void onLinkCreate(String url, BranchError error) {
if (error == null) {
Log.i("MyApp", "got my Branch link to share: " + url);
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, "News Number\n");
sharingIntent.putExtra(Intent.EXTRA_TEXT, url);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
}
});
}
}
can anyone help??
thanks in advance.
It seems like you might be trying to make a new Activity for each "page" of a ViewPager. The Android support library already has their own ViewPager that uses fragments.
You basically need three things to use a ViewPager:
The ViewPager itself
An adapter for the ViewPager
The fragment that will be used in the ViewPager (esentially the "template" that will be used for each "page" in the ViewPager)
First, we'll create the fragment. This is just a simple example that uses only one TextView, but it will work for any amount of views and data. You'll notice that static method "newInstance()" that creates and returns an instance of this fragment. Google recommends using this method to instantiate new Fragments for a ViewPager as it makes passing data to the fragment much easier. All fragments have a "setArguments()" method that lets you pass in a Bundle when you instantiate it with whatever data you want. The method "getArguments()" can be used to access that bundle and get the values out of it in onCreate() or onCreateView(). This is how you pass in an object or objects to bind its data to the views. In this example, were just passing in a String and setting that String to a TextView. You'll see how it's used when we create the adapter for the ViewPager.
//You should be using android.support.v4.app.Fragment here
public class ExampleFragment extends Fragment {
private static final String DAY_NAME_KEY = "day_name";
private TextView dayName;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_example, container, false);
dayName = (TextView) fragmentView.findViewById(R.id.day_name);
return fragmentView;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//Set the name of the day to the dayName TextView
String day = getArguments().getString(DAY_NAME_KEY);
dayName.setText(day);
}
public static ExampleFragment newInstance(String day) {
Bundle bundle = new Bundle();
bundle.putString(DAY_NAME_KEY, day);
ExampleFragment fragment = new ExampleFragment();
fragment.setArguments(bundle);
return fragment;
}
}
Now, we need to make an adapter that will create the views when the ViewPager is swiped. You need to extend either FragmentPagerAdapter or FragmentStatePagerAdapter. FragmentPagerAdapter is used for a small number of static fragments and it will use more memory. So you only want to use this if you have 4 or 5 pages and aren't adding any more dynamically.
For your case, it sounds like you want to swipe through a variable number of pages that are dynamically added, so you want to use FragmentStatePagerAdapter. It's optimized for memory efficiency and it will handle the saving and restoring of the fragments' state for you.
The adapter is simple.
First, you need to make your constructor match the super class's constructor. What that means is that your constructor must have a FragmentManager parameter. All you do with that is pass it to the super class. (You'll see below.)
Secondly, you have to implement just 2 methods from the FragmentStatePagerAdapter class:
public Fragment getItem(int position)
and
public int getCount()
getItem will be automatically called by the ViewPager when it is swiped. You just have to tell it what type of fragment to return. We'll be using the newInstance() method from the ExampleFragment class here.
getCount is the number of views that your ViewPager will be using. For example, I will have an ArrayList that will contain 7 strings (one for each day of the week). I want each one of those strings to be displayed on a different page of my ViewPager. So I'm just going to return the size of the ArrayList for this method.
Here's the class:
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
//A reference to the array of data that will be used to populate
//each fragment. In this case it's an array of Strings, but it
//could be any type of object. The Strings within this array are what
//we'll be passing to the newInstance() method of each fragment.
private ArrayList<String> days;
//Constructor must take a FragmentManager to match the superclass.
public ViewPagerAdapter(FragmentManager fm, ArrayList<String> days) {
//All you have to do with the fragment manager is pass it to super
super(fm);
//The array will be passed in when we create the Adapter in our Activity
this.days = days;
}
#Override
public Fragment getItem(int position) {
/*
Automatically called when another page is needed.
The adapter will keep track of the position of the current page
so the first time this is called, it will be 0, then when a
swipe occurs, it will be one. If it is swiped backward, it will go back to 0.
So when the position is 0, a new Fragment will be created and the
String at days.get(0) ("Monday") will be passed to it.
*/
return ExampleFragment.newInstance(days.get(position));
}
#Override
public int getCount() {
return days.size();
}
}
Now we just have to set the adapter for the ViewPager in our Activity and it will automatically handle swipes for us.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> daysOfWeek = new ArrayList<>();
daysOfWeek.add("Monday");
daysOfWeek.add("Tuesday");
daysOfWeek.add("Wednesday");
daysOfWeek.add("Thursday");
daysOfWeek.add("Friday");
daysOfWeek.add("Saturday");
daysOfWeek.add("Sunday");
ViewPager pager = findViewById(R.id.view_pager);
//Pass the activity's fragmentmanager by calling getSupportFragmentManager().
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), daysOfWeek);
pager.setAdapter(adapter);
}
}
This is what we get (I've added some padding and color to make it clear):
As for changing the way the pages "turn" (for example, like a newspaper), you need to look into PageTransformer
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 A, containing a listview. To this listview I add a listheader containing a ViewPager that pages through childfragments.
When the user clicks an item in the list, the listfragment A gets replaced by a detail-view-fragment of that listitem.
I want the user to be able to go back to the list by clicking the back button.
So far everything works, except when the user presses the back button to pop the detail fragment from the stack to get back to the listview fragment A, the app crashes with an
java.lang.IllegalArgumentException: No view found for id 0x7f06002e (com.makamedia.hockeyweb:id/news_header_pager) for fragment NewsHeaderFragment{41f7b6f8 #0 id=0x7f06002e android:switcher:2131099694:0}
My suspicion is, that maybe the nested fragments for the viewpager in the listheader get recreated before the viewpager gets recreated, thus crashing the app, but I am not sure.
Any help is appreciated!
My ViewPagerAdapter for the listheader-viewpager (removed some unrelated code):
public class NewsHeaderAdapter extends FragmentPagerAdapter {
private int mCount;
public final NewsListAdapter mListAdapter;
public NewsHeaderAdapter(FragmentManager fm, int count, long autoSwipeInterval, NewsListAdapter adapter) {
super(fm);
this.mCount = count;
this.mListAdapter = adapter;
}
#Override
public Fragment getItem(int pos) {
return NewsHeaderFragment.getNew(this.mListAdapter.getItem(pos));
}
public void setCount(int newCount){
if(newCount < 1){
this.mCount = 1;
} else if(newCount >= this.mListAdapter.getCount()){
this.mCount = this.mListAdapter.getCount();
} else {
this.mCount = newCount;
}
}
#Override
public int getCount() {
return mCount;
}
#Override
public CharSequence getPageTitle(int position) {
return this.mListAdapter.getItem(position).getTitle();
}
}
My news detail fragment (pretty straight forward):
public class NewsHeaderFragment extends Fragment {
private NewsItem mNewsItem;
private TextView mHeaderNewsBigTitle;
private ImageView mHeaderNewsBigImage;
// Convenience method for creating a new fragment with parameters
public static NewsHeaderFragment getNew(NewsItem item){
NewsHeaderFragment fragment = new NewsHeaderFragment();
Bundle args = new Bundle();
args.putSerializable(Constants.SIG_NEWS_ITEM, item);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.row_big_news, container, false);
Bundle newsHeaderArgs = getArguments();
mNewsItem = (NewsItem)newsHeaderArgs.getSerializable(Constants.SIG_NEWS_ITEM);
setupUI(rootView);
fillUI();
return rootView;
}
private void fillUI() {
mHeaderNewsBigTitle.setText(mNewsItem.getTitle());
Picasso.with(getActivity()).load(mNewsItem.getImageBig2x()).into(mHeaderNewsBigImage);
}
private void setupUI(View rootView) {
mHeaderNewsBigTitle = (TextView) rootView.findViewById(R.id.news_big_title);
mHeaderNewsBigImage = (ImageView) rootView.findViewById(R.id.news_big_img);
}
}
My viewpager is declared in xml in a row-layout and added like so:
private void addHeaderPager(int count) {
if(mNewsListAdapter != null && mNewsListAdapter.getCount()>0) {
if (count >= mNewsListAdapter.getCount()) {
count = mNewsListAdapter.getCount() - 1;
}
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mHeader = (RelativeLayout) inflater.inflate(R.layout.row_big_news_pager, null);
mHeaderPager = (ViewPager) mHeader.findViewById(R.id.news_header_pager);
mHeaderPagerAdapter = new NewsHeaderAdapter(getChildFragmentManager(), count, 6000, mNewsListAdapter);
mHeaderPager.setOffscreenPageLimit(count);
mHeaderPager.setAdapter(mHeaderPagerAdapter);
// Bind the title indicator to the adapter
CirclePageIndicator circleIndicator = (CirclePageIndicator) mHeader.findViewById(R.id.news_header_pager_indicator);
circleIndicator.setViewPager(mHeaderPager);
mNewsListView.addHeaderView(mHeader);
}
}
Are you sure tha you use the right FragmentManager in addHeaderPager()?
I normally use getFragmentManager() and if there is a parent fragment I have to use getParentFragment().getFragmentManager() - if I don't I get the same error ("No view found for id") when trying to replace the current visible fragment.
I have created a viewpager layout, a class that extends FragmentActivity and a fragment. What I want is that each fragment get's passed in what position it is within the viewpager. So first viewpager is created getting the argument 0, second getting 1 etc. Then if I scroll one way or another these numbers remain a true count.
The problem is the first time a fragment is created, it seems to be created twice so the position passed is 0 then 1. However I can't scroll back but I know for sure the class is being called twice. Now as I scroll forward the position increases incrementally by one. However if I scroll back it drops immediately to three on just one page back, then continues to drop past the 1 to 0 so now I can finally see my layout for 0.
I have this:
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
PracticeFragment fragment = new PracticeFragment();
getAll.putInt("position", position);
fragment.setArguments(getAll);
return fragment;
}
#Override
public int getCount() {
return numberofQ;
}
}
It first of all runs getItem twice before even going to my fragment class so that the position is 0 then 1. Then when it gets to my fragment class it makes a layout fine, I scroll through a few (3 or 4) new pages and it adds one to the position each time then when I scroll back it says it is zero or two then the numbers continue to be just as sporadic. Finally suddenly when I scroll back to the beginning the position is again 0 so my fragment for position 0 is suddenly displayed.
I don't understand what's happening, so I'm wondering what the mistake is?
public class PracticeFragment extends Fragment {
TextView question, explain;
private ScrollView sv;
private boolean starActionBar;
private final static int version = Consts.SDKversion;
ArrayList<RadioButton> rbArray;
ArrayList<LinearLayout> lArray;
ArrayList<ImageView> ivArray;
int iRow;
SQLite info;
private String correctAnswer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
info = new SQLite(getActivity());
starActionBar = PreferenceManager.getDefaultSharedPreferences(
getActivity()).getBoolean("star", true);
setHasOptionsMenu(true);
}
#Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
for (RadioButton r : rbArray) {
if (r.isChecked()) {
r.performClick();
}
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.activity_pm_fragment, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.activity_main, container, false);
lArray = new ArrayList<LinearLayout>();
rbArray = new ArrayList<RadioButton>();
ivArray = new ArrayList<ImageView>();
lArray.add((LinearLayout) rootView.findViewById(R.id.PM_LinLay0));
lArray.add((LinearLayout) rootView.findViewById(R.id.PM_LinLay1));
lArray.add((LinearLayout) rootView.findViewById(R.id.PM_LinLay2));
lArray.add((LinearLayout) rootView.findViewById(R.id.PM_LinLay3));
lArray.add((LinearLayout) rootView.findViewById(R.id.PM_LinLay4));
for (LinearLayout l : lArray) {
l.setOnTouchListener(PracticeFragment.this);
l.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (((ViewGroup) v).getChildAt(0).isEnabled()) {
((ViewGroup) v).getChildAt(0).performClick();
}
}
});
}
rbArray.add((RadioButton) rootView.findViewById(R.id.radio0));
rbArray.add((RadioButton) rootView.findViewById(R.id.radio1));
rbArray.add((RadioButton) rootView.findViewById(R.id.radio2));
rbArray.add((RadioButton) rootView.findViewById(R.id.radio3));
rbArray.add((RadioButton) rootView.findViewById(R.id.radio4));
ivArray.add((ImageView) rootView.findViewById(R.id.ivradio0));
ivArray.add((ImageView) rootView.findViewById(R.id.ivradio1));
ivArray.add((ImageView) rootView.findViewById(R.id.ivradio2));
ivArray.add((ImageView) rootView.findViewById(R.id.ivradio3));
ivArray.add((ImageView) rootView.findViewById(R.id.ivradio4));
rootView.findViewById(R.id.bNext).setVisibility(View.GONE);
rootView.findViewById(R.id.bPrevious).setVisibility(View.GONE);
sv = (ScrollView) rootView.findViewById(R.id.svMain);
info.open();
iRow = Integer.valueOf(info.getEverything(getArguments(), getArguments().getInt("position"), "next"));
Cursor c = info.getCursor(iRow);
((TextView) rootView.findViewById(R.id.tvQuestion))
.setText((getArguments().getInt("position") + 1) + ") " + c.getString(2));
explain = (TextView) rootView.findViewById(R.id.tvExplain);
explain.setText(c.getString(9));
explain.setVisibility(View.GONE);
correctAnswer = c.getString(8);
String[] aArray = { c.getString(3), c.getString(4), c.getString(5),
c.getString(6), c.getString(7) };
c.close();
info.close();
int o = 0;
int pos = 0;
for (String s : aArray) {
LinearLayout l = lArray.get(pos);
if (s.contentEquals("BLANK")) {
l.setVisibility(View.GONE);
} else {
l.setVisibility(View.VISIBLE);
rbArray.get(pos).setText(s);
rbArray.get(pos).setOnClickListener(null);
if (o % 2 == 0) {
l.setBackgroundColor(Consts.colorAlt);
}
o++;
}
pos++;
}
return rootView;
}
}
However if I comment out everything but the viewgroup and return rootview - still the same problem.
initialize the getAll every time as a new object in getItem()
make your fragment class static
and create one method in PracticeFragment
static PracticeFragment newInstance(int num) {
PracticeFragment f = new PracticeFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
and change in adapter
#Override
public Fragment getItem(int position) {
return PracticeFragment.newInstance(position);
}
Subclassing it fixed the problem!
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.