How can I add a simple static header to my listview inside a listFragment? I want to create the header from an xml def and add it through inflation.
My onCreateView:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View detailList = inflater.inflate(R.layout.detail_fragment, container, false);
View detailListHeader = inflater.inflate(R.layout.daily_sales_header, null, false);
container.addView(detailListHeader, 0);
return detailList;
}
This creates the header, but it is not above the listview, rather the listview appears underneath the header, ie the header is overlaying the listview.
Any hints on the correct implementation?
Putting hackbod's description into code for you since his answer created more questions before the answers came. Sometimes I just want the fish. I don't always need to know how the net is made...
To start with, create a layout that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myListViewWithHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:textStyle="bold"
android:textSize="20sp" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Then, in your onCreateView method you do this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.myListViewWithHeader, null);
return view;
}
The header can now be populated by doing this:
// get the header view
TextView headerView = (TextView) getView().findViewById(R.id.header);
headerView.setText("Header text goes here");
Notice that my header is a TextView, but it can be replaced with another view if you like. In that case you will need to do a getView().findViewById(R.id.xxxxx) for each view inside the header you want to work with
You should NEVER EVER be adding views directly to the container in onCreateView(). Please read the documentation: http://developer.android.com/reference/android/app/Fragment.html#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
Also see the various sample code in the Fragment documentation, as well as the API demos: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/index.html
There is nothing special about using a Fragment here. Just build a view hierarchy containing a ListView like you normally would in an Activity or elsewhere. You always need to return one View from onCreateView; this is the root of your hierarchy.
For example you could make the ListView and then use this to add a header to it: http://developer.android.com/reference/android/widget/ListView.html#addHeaderView(android.view.View)
Related
I've been developing an app on Android 5.1.1, and everything works fine. But when I test it on a 4.0.4 device, none of the buttons display any text. Any idea why this would be?
Each button is the UI of a fragment. This is the layout, named just_a_button.xml:
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/button_copper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#fff"
android:visibility="gone"/>
This is an example of how the fragments set up their views:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final Button button = (Button) inflater.inflate(R.layout.just_a_button, container, false);
button.setText(R.string.member_info);
// set click listener omitted
return button;
}
The button's visibility is controlled by an event receiver. The button is shown as expected, and its click listener works. There's just no text on it.
Edit: The solution was to put the button inside a layout. I'm still curious if this requirement was ever documented, and why only the text seems to be affected when the button is the root view.
Instead of this
button.setText(R.string.member_info);
use
button.setText(getActivity().getResources().getString(R.string.member_info));
You are directly defining string resource, but setText() takes string as parameter.
Edit:
change you xml like below and then findviewbyid for your button
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/Mybutton"
style="#style/button_copper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#fff"
android:visibility="gone"/>
</LinearLayout>
In your fragment onCreateView() do as below :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.just_a_button, container, false);
Button button = (Button) view.findViewById(R.id.Mybutton);
button.setText(getActivity().getResources().getString(R.string.member_info));
// set click listener omitted
return view;
}
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 am trying to make a particular nested FrameLayout visible dynamically. However, i am getting NullPointerException when i try to access the view outside of my fragment's onCreateView() method. So here is my implementation.
private View myView;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View fragmentView = inflater.inflate(R.layout.listView, container, false);
this.myView = fragmentView;
...
return fragmentView;
}
#Override
public void apiCompleted(ApiResult apiResult, HttpRequest httpRequest) {
if(myLocationManager.hasLocation()){
FrameLayout flayout = (FrameLayout) myView.findViewById(R.id.ldrawlayout);
flayout.setVisibility(View.VISIBLE);
}
}
listView.xml
<LinearLayout 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/background_gray"
tools:context=".fragment.MallListFragment"
android:orientation="vertical">
<ListView
android:id="#+id/lv_malls"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
rowlist.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row_mallx"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:paddingBottom="7dp">
<FrameLayout
android:id="#+id/ldrawlayout"
>
...
</FrameLayout>
</RelativeLayout>
LOGCAT (onCreateView method is called first)
01-15 18:40:16.905 7633-7633/? V/onCreateView METHOD CALLEDīš onCreateView
01-15 18:40:17.280 7633-7633/? V/APICOMPLETED METHOD CALLEDīš apiCompleted
Ok, I see the problem. You want to access the row-layout, but your listview has multiple versions of this layout, that mean you can not access the row layout from the activity, you have to do it in your listadapter or you give your single rows in the listadapter an unique id such as row.setId(row.getId + positionOfRow)
LayoutInflater Inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = Inflater.inflate(R.layout.row_mallx, null);
FrameLayout flayout = (FrameLayout) view .findViewById(R.id.ldrawlayout);
flayout.setVisibility(View.VISIBLE);
try this code in on apiCompleted
Are your sure that the onCreateView() method is called before the apiCompleted() method.
If yes, you should be able to access the view any where in your code as long as you hold the reference to it.
You can add some logs to see the order that the functions get called
I want to display a graph in a fragment, but I didn't found many information about how to use GraphView in general. Can someone please help me to display a simple graph?
I started with this: http://android-graphview.org/#doc_createsimplegraph but don't get it working in a fragment.
What I did was to create a fragment_graph.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="250dip"
android:id="#+id/graph1"
android:background="#102f65" />
</LinearLayout>
and add the relevant code in the Fragment class:
public class GraphFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_graph, container, false);
// add the data here if necessary
// ...
LinearLayout layout = (LinearLayout) view.findViewById(R.id.graph1);
layout.addView(graphView);
return view;
}
// ...
}
Then you can use the fragment "as is".
Most credit actually goes to vogella.
define a empty LinearLayout with fixed width and height in your layout.xml file and then add the graphview view to it.
Layout
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="250dip"
android:id="#+id/graph1" />
Java
LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
layout.addView(graphView);
Just for the record:
You cannot use it in connection with ScrollViews. If a ScrollView is wrapping your LinearLayout the lib doesn't show anything.
I am having a fragment that send request to server and download json , then parse it into a listview , somehow i can't reach the view properly.below is some part of my apps , this is my first touch on listview with fragment , for some reason i only allow to use Fragment so i choose 'setAdapter' instead of 'setListAdapter' to be my adapter
myfragment.java
public class gallery extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View myFragmentView = inflater.inflate(R.layout.tab_frag2_layout,
container, false);
return myFragmentView;
}
public void onActivityCreated(Bundle savedInstanceState) {
.........
.........
.........
setAdapter(colorAdapter);
}
layout.tab_frag2_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/list_padding"
android:paddingRight="#dimen/list_padding"
android:tag="listf" />
</LinearLayout>
My expectation is using
MyListView = (ListView)myFragmentView.findViewById(R.id.list);
to get my view , but it doesn't work that way...
Now I just want to get my listview and apply
MyListView.setAdapter(colorAdapter) to it
any help would be appreciated, thanks
Option1: Since your fragment layout consists of just a simple ListView.
Consider using
public class gallery extends ListFragment
Then you can use this code to get your listview.
myFragmentView.getListView()
Option2: As Nickolaus mentioned, you need a custom id if you want to use findViewById.
android:id="#+id/listview1"
If you don't want to use a ListFragment, you need to add a custom id (android:id="#+id/custom_id") then you can use findViewById to find the ListView