I have created a fragment and want to start a dialogue on a button click on which i would display n numbers of texts distributed vertically using Linear layout vertical orientation. To begin with i have created a textview which i am populating dynamically. But i get a null pointer exception saying the any of the layout i referenced here points to NULL.
View view,tempView;
TextView myName, myPhNo, myEmail, myDob;
ImageButton selectRingTone;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_profile, container, false);
tempView = inflater.inflate(R.layout.fragment_selectsong, container, false);
myName = (TextView)view.findViewById(R.id.username);
myPhNo = (TextView)view.findViewById(R.id.userPhNo);
myEmail = (TextView)view.findViewById(R.id.useremailId);
myDob = (TextView)view.findViewById(R.id.userdob);
selectRingTone = (ImageButton)view.findViewById(R.id.selectRingTone);
setUserProfileData();
//setUserTextStatus();
//setUserAudioStatus();
selectRingTone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
chooseAndSetRingTone();
}
});
return view;
}
private void chooseAndSetRingTone(){
final Dialog fbDialogue = new Dialog(view.getContext(), android.R.style.Theme_Black);
fbDialogue.getWindow().setTitle("Select your audio status song");
fbDialogue.getWindow().setBackgroundDrawable(new ColorDrawable(Color.argb(100, 0, 0, 0)));
fbDialogue.setContentView(R.layout.fragment_selectsong);
getSongsAndFillDialogue();
fbDialogue.setCancelable(true);
fbDialogue.show();
}
private void getSongsAndFillDialogue(){
LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout container = (LinearLayout) tempView.findViewById(R.id.eachRingToneSong);
TextView tv = new TextView(tempView.getContext());
tv.setText("Hi hello");
Button b = new Button(tempView.getContext());
b.setText("abcde");
container.addView(tv);
container.addView(b);
}
XML Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLyt"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="#+id/scrollCotainerForRingToneSongs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/eachRingToneSong"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--<TextView
android:id="#+id/song1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="abcde"
/>-->
</LinearLayout>
</ScrollView>
</RelativeLayout>
you are creating View for your Dialog in onCreateView method:
tempView = inflater.inflate(R.layout.fragment_selectsong, container, false);
and fulfilling it using getSongsAndFillDialogue method, but you are setting for your Dialog another new instance passing only resource id:
fbDialogue.setContentView(R.layout.fragment_selectsong);
when you are passing just id then Dialog is inflating this layout by itself (just like you). So there are two layouts created, one in Activity - fulfilled, and one created "automatically" by setContentView method, but not touched at all by your methods (so it stays empty)
instead of passing resource id pass already prepared tempView, like below:
fbDialogue.setContentView(tempView);
Related
I have a fragment with his class:
public class FormatShortFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.bag_format_short, container, false);
return rootView;
}
}
And this is his layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</LinearLayout>
</RelativeLayout>
This fragment is shown by a FragmentPageAdapter.
The layout will grow when an user add an item from server (the origin of the item doesn't matter), and this item will be an horizontal linearlayout, with textview and edittext (item_name, item_value). This value can be modifiable, so must be an edittext, also, this edittext will receive values periodically from server, so can be updated automatically.
After explain this, how can I add this linearLayouts and his subviews to the GUI dynamically? and when should I update the interface?
Thanks a lot, any help is good received, I'm really lost on this on this themes.
EDITED WITH MODIFICATIONS:
I have modified the code in this way:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.bag_format_short, container, false);
return rootView;
}
#Override
public void onResume() {
super.onResume();
LinearLayout parentLinear = (LinearLayout) getActivity().findViewById(R.id.short_container);
for (int i = 1; i<10; i++ ){
LinearLayout innerLinear = (LinearLayout) new LinearLayout(getActivity());
TextView itemName = new TextView(getActivity());
itemName.setText("Nombre");
EditText itemValue = new EditText(getActivity());
itemValue.setText("Valor");
innerLinear.addView(itemName);
innerLinear.addView(itemValue);
parentLinear.addView(innerLinear);
}
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
And the fragment layout has been modified on this way:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<LinearLayout
android:id="#+id/short_container"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</LinearLayout>
</RelativeLayout>
Now the layout is growing in each for iteration.
In this point i have another problems, I hope you can help me with this.
- How can I generate a LayouParams object with attributes like gravity or weigth?
- How can I pass data from MainActivity to the Fragment?
- And how can i force the Fragment view to be raloaded with new data?
Also i need to know how bind a clickListener event to programatically linearLayouts added, i need modify some values on server depending on the name and the edited value.
Thanks a lot for this, you are saving my life.
you Can easily Update UI of Fragment on Button click or any event just
Like in Activity. You can get any view by
getActivity().findViewById()
See Example, It will help you to undersatand:-
public class FragmentTab3 extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragmenttab3, container, false);
return rootView;
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onStart() {
super.onStart();
LinearLayout linear = (LinearLayout) getActivity().findViewById(R.id.linear);
Button button = new Button(getActivity());
button.setText("Click Me");
linear.addView(button);
}
#Override
public void onStop() {
super.onStop();
}
}
If you want to add subview to a layout dynamically, take a look at RecyclerView in android documentation. Sounds like what you're looking for.
I am having trouble getting EditText to dynamically populate in TableView, this is only happening on non Lollipop Devices in a fragment (In particular an appcompat fragment, i have not tested in a regular framgent). When the same code is run in an activity it works fine.
Here is my fragment code on creating the row of edit texts.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_daily_field_report, container, false);
tableLayout = (TableLayout) view.findViewById(R.id.equipmentLayout);
context = getActivity().getBaseContext();
this.inflater = inflater;
activityContext = getActivity();
return view;
}
private void createRow(Equipment equipment, final int editId) {
TableRow row = new TableRow(context);
EditText equipmentName = (EditText) getActivity().getLayoutInflater().inflate(R.layout.table_text_edittext, row, false);
EditText headerQty = (EditText) getActivity().getLayoutInflater().inflate(R.layout.table_number_edittext, row, false);
EditText headerHrs = (EditText) getActivity().getLayoutInflater().inflate(R.layout.table_number_edittext, row, false);
equipmentName.setText(equipment.title);
if (equipment.Qty != 0) {
headerQty.setText(Integer.toString(equipment.Qty));
}
if (equipment.Hrs != 0) {
headerHrs.setText(Integer.toString(equipment.Hrs));
}
equipmentName.setId(editId);
this.fields.add(equipmentName);
this.fields.add(headerQty);
this.fields.add(headerHrs);
row.addView(equipmentName);
row.addView(headerQty);
row.addView(headerHrs);
tableLayout.addView(row);
rows.add(new myTableRow(equipment, equipmentName, headerHrs, headerQty));
}
And Here are the edit text Xml layouts.
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_weight="1"
android:padding="5dp"
android:gravity="center"
android:layout_height="wrap_content"
android:inputType="text"
android:ems="10"
android:id="#+id/pumptruckQty"
android:layout_column="1"/>
I figured out what was causing the issue. When creating the TableRow to add to the TableLayout i was using the wrong context. The context used to create the Row should be the context of the LayoutInflater that is given in the onCreateView of the fragment.
I have the following fragment working in view pager:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/window_background"
android:id="#+id/font"
tools:context="com.cuentos.lib.cuentosmusicales.Libro">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:gravity="center"
android:id="#+id/titleBook"
android:textSize="25sp"
android:textColor="#2211CC"
android:text="#string/hello_blank_fragment" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/titleBook"
android:id="#+id/textBook"
android:textSize="15sp"
android:textColor="#44BB11"
android:text="#string/hello_blank_fragment" />
</RelativeLayout>
and i want to modify textview values from fragment class
public class Libro extends Fragment {
String titleLibro;
String text;
TextView title, text1;
public Libro() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_libro, container, false);
title = (TextView) view.findViewById(R.id.titleBook);
text1 = (TextView) view.findViewById(R.id.textBook);
title.setText("hi friends");
text1.setText("text");
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_libro, container, false);
}
}
So, I detect im not able to change data because there is no change, so how I can instanciate textview in fragment?
First, you're inflating your view two times. There's one on the first line of the onCreateView, which is the one that you modify the TextViews, but in the return statement you create and return another, you're not returning the one you modified, but a new one instead, so the view that will be presented in the UI is the not modified.
Also, you're calling the findViewById in the wrong lifecycle stage. Notice that onCreateView returns the view that will be present in your fragment. It's not possible to retrieve a view component like yours TextViews that way, because the view itself doesn't exists yet.
The right method to modify your view components is in the onViewCreated:
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
title = (TextView) view.findViewById(R.id.titleBook);
text1 = (TextView) view.findViewById(R.id.textBook);
title.setText("hi friends");
text1.setText(text);
}
Try setting the text when overriding your Fragments onActivityCreated or onResume methods.
I have a RelativeLayout containing a TextView.
I want to append a new TextView under the existing TextView programmatically in the onCreateView method, but what happens when I try to do so, is that the TextView I add programmatically gets overlapped with the existing one.
More details below:
public static class ContentTours extends Fragment{
public static String TOUR_NAME= "tour_info";
View view = getView();
TextView contentTour;RelativeLayout toursView;
public ContentTours(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.tours_view, container, false);
toursView = (RelativeLayout) view.findViewById(R.id.rel_layout);
contentTour = (TextView) view.findViewById(R.id.tours);
contentTour.setText(getArguments().getString("2"));
ViewGroup.LayoutParams stt = contentTour.getLayoutParams();
TextView nt = new TextView(getActivity().getBaseContext());
nt.setText(getArguments().getString("1"));
toursView.addView(nt, new ViewGroup.MarginLayoutParams(stt));
return view;
}
}
I have a RelativeLayout containing the TextView. tours_view.xml:
<RelativeLayout android:id="#+id/rel_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="16dp">
<TextView android:id="#+id/tours" android:clickable="true"
android:background="?android:selectableItemBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:text="Lorem ipsum"/>
</RelativeLayout>
the reason why I have a Fragment class is that tours_view.xml is a layout that I am applying to another FrameLayout.
By default in a RelativeLayout, the views overlap if there is no relation defined.
What you should do for your requirement is create a relation(rule) between the TextView to be added and the already present TextView.
RelativeLayout.LayoutParams stt = (RelativeLayout.LayoutParams) contentTour.getLayoutParams();
Now, add a rule
stt.addRule(RelativeLayout.BELOW, R.id.tours);
RelativeLayout.BELOW, so that the new TextView is below your old one. Hope this helps.
Hi there (and thanks in advance),
I have an application with a Google Play Store-like layout (using PagerTabStrip with 5 sub fragments). In some of those fragments I will need to display a little info regarding the last time the data was updated.
I immediately thought of creating a fragment (LastUpdatedFragment) which I would then add (nest) to the fragments I needed. At first, and since the last updated date was supposed to be the same for every screen, things were working (I simply added the fragment in the xml of the parent Fragments I needed and inside onCreateView I would put the date in the TextView), but after some changes I now need to send a specific date for each one of these LastUpdatedFragment instances.
I came up with one way - creating new custom attributes for my Fragment and then I would set the date I wanted. After some reading I stumbled across a easier way (Fragments within Fragments - dinamically adding the fragment using FragmentManager) - I simply needed the parent Fragment to handle the input parameters and pass it to the child fragment.
The problem is that, although I get no errors I also get no child fragment, it just does not display. I would be grateful if you could guide me in the right direction.
ScoreBoardFragment.java -> Parent Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_scoreboard, container,
false);
for (int i = 0; i < tvCount; i++) {
tvName = "f_scoreboard_header_tv" + String.valueOf(i);
resID = getResources().getIdentifier(tvName, "id",
_activity.getPackageName());
header = (TextView) rootView.findViewById(resID);
header.setTypeface(MyGlobalConfig.getInstance().getHeadersFont());
}
FragmentManager childFragMan = getChildFragmentManager();
FragmentTransaction childFragTrans = childFragMan.beginTransaction();
LastUpdatedFragment fragB = new LastUpdatedFragment();
childFragTrans.add(R.id.FRAGMENT_PLACEHOLDER, fragB);
childFragTrans.addToBackStack("B");
childFragTrans.commit();
return rootView;
}
fragment_scoreboard.xml (simplified but displaying everything else)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/FRAGMENT_PLACEHOLDER"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
style="#style/ListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/f_scoreboard_header_tv0"
style="#style/ListViewRowHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#" />
</LinearLayout>
<ListView
android:id="#+id/f_scoreboard_lvbody"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true" >
</ListView>
</LinearLayout>
LastUpdatedFragment.java -> Child Fragment
public class LastUpdatedFragment extends Fragment{
private View rootView;
private TextView tv;
private Context ctx;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(
getActivity()));
this.ctx = getActivity().getApplicationContext();
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_date, container,
false);
tv = (TextView) rootView.findViewById(R.id.f_date_tv);
tv.setTypeface(MyGlobalConfig.getInstance().getBodyFont());
tv.setText(getString(R.string.lastupdated) + ": " + Util.getLastUpdated(ctx));
return rootView;
}
}
fragment_date.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/f_date_tv"
style="#style/LastUpdatedTV"
android:layout_width="match_parent"
android:text="Data de última actualização: 27/12/2014 21:30" />
</LinearLayout>
Try to use FrameLayout instead of LinearLayout as Placeholder.