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.
Related
So I am still fairly new to working with Android Studio and everything in it. I have been stuck on trying to get fragments to communicate directly with each other. Here I'm simply just trying to set the TextView text element within one of my fragments. I have looked for hours and tried a lot, but I'm not sure what to do. Also, I am implementing my fragments through code in a FrameLayout.
Here is my fragment whose text value I'm trying to edit:
public class ReceivingFrag extends Fragment {
TextView sender;
public void updateText(String text) {
sender.setText(text);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_sender, container, false);
sender = (TextView) v.findViewById(R.id.sender);
return v;
}
}
I believe my root problem is that getView() and sender both return Null. I also understand that fragments are not technically views, but rather aid in the layout of views and ViewGroups. Any help is appreciated.
Not sure if it helps, but this is the method that calls the updateText() method within the ReceivingFrag class.
public void sendText(String text){
ReceivingFrag frag = new ReceivingFrag();
getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
getSupportFragmentManager().executePendingTransactions()
frag.updateText(text);
}
**Edit:
This is my MainActivity class that is calling and creating the Fragment:
public class MainActivity extends AppCompatActivity implements SendingFragment.TextClicked {
private static final String TAG = MainActivity.class.getSimpleName();
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] myStringArray = {"Hello", "Nice To See You", "Bye"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, myStringArray);
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
sendText("Hello");
}
#Override
public void sendText(String text){
ReceivingFrag frag = new ReceivingFrag();
getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
getSupportFragmentManager().executePendingTransactions();
frag.updateText(text);
}}
**Edit 2:
This is the MainActivity layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/apk/tools"
xmlns:tools2="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<EditText android:id="#+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/edit_message"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="sendMessage"
android:text="#string/button_send"/>
</LinearLayout>
<ListView android:id="#+id/mobile_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/receiving_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></FrameLayout></LinearLayout>
And this is the layout for the Fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/sender"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/frag_sender"
android:background="#color/gray"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"/></LinearLayout>
Solution:
So as mentioned below, the runtime error was fixed by adding
#Override
protected void onResume() {
super.onResume();
sendText("hello");
}
to the MainActivity class. After reading from https://developer.android.com/guide/components/fragments.html#Lifecycle
I think the statement
"Once the activity reaches the resumed state, you can freely add and remove fragments to the activity. Thus, only while the activity is in the resumed state can the lifecycle of a fragment change independently."
best explains the situation and why the error initially occurred.
If you instead put the sendText() in your onResume() like this,
#Override
protected void onResume() {
super.onResume();
sendText("Hello");
}
It will not give you the Null Pointer Exception. The fragment is still null when you call on it from onCreate().
Change your Fragment to this:
public class ReceivingFrag extends Fragment {
private TextView sender;
public void updateText(String text) {
sender.setText(text);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_sender, container, false);
sender = (TextView) v.findViewById(R.id.sender);
return v;
}
}
and in your activity, before calling the updateText method, make sure the fragment transaction has executed by doing:
public void sendText(String text){
ReceivingFrag frag = new ReceivingFrag();
getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
getSupportFragmentManager().executePendingTransactions();
frag.updateText(text);
}
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);
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'm using a fragment to show a GridView with some images and a Button to add new Images. The GridView works fine, but my Button's onClick method is never called.
This is my Fragment's onCreateView method:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_picture_grid_view, container, false);
addPictureButton = (Button) rootView.findViewById(R.id.fragment_grid_view_add_button);
addPictureButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CameraOrAlbumDialogFragment dialogFragment = new CameraOrAlbumDialogFragment();
dialogFragment.show(mContext.getSupportFragmentManager(), "CameraPicker");
}
});
imageGridView = (GridView) rootView.findViewById(R.id.fragment_grid_view);
imageGridView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
}
In my onActivityCreated method I do all the Adapter stuff for my GridView and it works normally, it can capture my clicks and longClicks. The only thing not working is the Button's onCLick method. I can see the Button icon changing when I touch it, but the functions inside my onClickListener method are never called. Any help?
EDIT
This is my fragment layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<GridView
android:id="#+id/fragment_grid_view"
android:layout_width="match_parent"
android:layout_height="150dp"
android:numColumns="auto_fit" >
</GridView>
<Button
android:id="#+id/fragment_grid_view_add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Add Picture" />
</LinearLayout>
EDIT2
Turns out that there was another button overlaping my button, so that button was receiving the onClick events instead of my button. I was able to figure it out when I used the Hierarchy view in Eclipse. Very usefull.
Try this.
public class CarCheckFrameFragment extends Fragment implements View.OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_car_check_frame, container, false);
Button button = rootView.findViewById(R.id.button);
button.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.button:
doSomething();
break;
}
}
}
I figured thet I had another View overlapping my button, that's why it was never called.
SO DUMB! Sorry.
You should use getChildFragmentManager() when using fragments inside other fragments.
Ok, this is my new problem;
I am trying to change the background color of a View inside a Fragment on touch Event.
It is already setup and working fine. But it seems the background just won't change of color.
I do suspect this happens because this view has also other views on it on fill parent So even if it changes color I won't be able to see it.
Anyhow I have already set up those views color to Color.TRANSPARENT but it still does not work...
Here is my xml file:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:id = "#+id/lay_1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/position"
android:id="#+id/pos"/>
<ViewFlipper
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/pos"
android:id="#+id/flipper_1"
>
<include layout="#layout/cart"/>
<include layout="#layout/ang"/>
<include layout="#layout/data_graph"/>
</ViewFlipper>
If you need more information don't mind asking for it.
Thanks a lot.
Luis.
I had a similar issue and you should try to create a method called at the oncreate of the fragment to update the inside of the fragment view (background color, text...)
ex:
public static LinearLayout getcolor(LayoutInflater inflater, ViewGroup container, boolean bf){
int i;
View v;
TextView t;
LinearLayout ll;
int r = (int)Math.round(Math.random()*255+1);
int g = (int)Math.round(Math.random()*255+1);
int b = (int)Math.round(Math.random()*255+1);
i=Color.argb(200,r,g,b);
if(bf){
ll = (LinearLayout )inflater.inflate(R.layout.fragment_card_front, container, false);
v=ll.findViewById(R.id.frag_card_front);
v.setBackgroundColor(i);
t=(TextView) ll.findViewById(R.id.textf);
t.setText(""+i);
}
else{
ll = (LinearLayout )inflater.inflate(R.layout.fragment_card_back, container, false);
v=ll.findViewById(R.id.frag_card_back);
v.setBackgroundColor(i);
t=(TextView) ll.findViewById(R.id.textb);
t.setText(""+i);
}
return ll;
}
public static class CardFrontFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout ll = (LinearLayout ) getcolor(inflater, container,true);
return ll;
}
}
public static class CardBackFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout ll = (LinearLayout ) getcolor(inflater, container,false);
return ll;
}
}