So I have two Fragments inside an Activity using a PageAdapter.
One of the Fragments is a Listview and the other is a GridView of images.
The fragments are created successfully but the ListView is empty
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View view = inflater.inflate(R.layout.eventlist ,container, false);
String[] x = new String[]{"AAA","BBB","CCC","AAA","BBB","CCC","AAA","BBB","CCC","AAA","BBB","CCC","AAA","BBB","CCC","AAA","BBB","CCC"};
ListView listView = (ListView) view.findViewById(R.id.listView);
ArrayAdapter<String> test = new ArrayAdapter<String>(getActivity().getBaseContext(), android.R.layout.simple_list_item_1,x);
listView.setAdapter(test);
return view;
}
XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<ListView
android:id="#+id/listView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
You should not check null for listview. But rather check if the list is empty.
Change it to listView.getChildCount()==0.
But I think you dont need to check because it will always be empty because it's a new created view. And no items on the list. If you want to check correctly, put the condition check after you set the adapter to the list.
Check if this works.
Related
Right so, I have a navbar layout. The <FrameLayout> in content_main is replaced with stand1.xml when the stand1 button in my navbar is pressed. This works without any issue.
Content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior" tools:showIn="#layout/app_bar_main"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"></FrameLayout>
</RelativeLayout>
stand1.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="match_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/Stand1list">
</ListView>
</LinearLayout>
from main activity
if (id == R.id.Stand1) {
fm.beginTransaction().replace(R.id.content_frame, new Stand1()).commit();
setTitle(R.string.Stand1);
Following tutorials online this is my Stand1.java file which is used to populate the a list with a array of strings
public class Stand1 extends Fragment {
ListView mList;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.stand1,container,false);
mList = (ListView) root.findViewById(R.id.Stand1list);
return root;
}
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
populateListView();
}
private void populateListView() {
String[] pair = {"Pair1","Pair2","Pair3","Pair4","Pair5"};
//build adapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.row_layout,pair);
mList.setAdapter(adapter);
}
}
and row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/text1"
xmlns:android="http://schemas.android.com/apk/res/android" />
This is working, It displays the 5 strings. However i want to make it so i can also have a check box in each row.
If i try place linear layout in row_layout.xml , i get error
ArrayAdapter requires the resource ID to be a TextView
I was following stackoverflow which sorted other errors which suggested that i had to make the list at class level and inflate it in onCreate.
I know i prob have to make an custom array adapter, but my problem is how do i deal with the inflation of the view in the on create.
Im not really sure how i go about doing this. So can somebody tell me from here, how do i go about having a check box in each row.
Thanks for the help
ArrayAdapter needs to know where to put the text from your string array. By default, it assumes the layout you pass it is a TextView and will set its text to one of the strings. If you pass it a more complicated layout, you need to tell it the id of the TextView you want it to use. You can do that with this constructor.
I'm using Chris Bane's "deprecated" Pull-to-Refresh library. Everything's working nicely. What I'm able to do:
1.) When there's content in the listview I can do a pull to refresh. I can see the progress dialog spinning and everything.
2.) On first load of the app if there's no data/empty listview, I can show the empty textview and I am able to do the same pull to refresh with the spinning progress bar showing.
But the second time I go to this listview (that's inside a Fragment), with empty data nothing happens. Can't do a pull to refresh -- the progress dialog doesn't show, doesn't even pull the layout. It just shows an empty text (that you can't pull anymore).
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/ptr_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:divider="#19000000"
android:dividerHeight="1dp"
android:fadingEdge="none"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:descendantFocusability="blocksDescendants"
app:ptrDrawable="#drawable/ic_logo_blue"
app:ptrRotateDrawableWhilePulling="false"
app:ptrScrollingWhileRefreshingEnabled="false"
app:ptrHeaderBackground="#EEEEEE"
app:ptrRefreshableViewBackground="#F7F7F7"
android:smoothScrollbar="true" />
<TextView
android:id="#+id/emptyView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:text="Empty list"
android:gravity="center"
android:visibility="gone"/>
I also tried replacing the RelativeLayout with LinearLayout, but the issue still exists.
Additional Info
Not sure if these are relevant:
The Fragment that contains the listview is inside a SlidingTab
The listview reference to the pull to refresh listview has a height of 0.
Here's the code to the Fragment's onCreateView()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
result = (RelativeLayout)inflater.inflate(R.layout.listview, container, false);
listView = (PullToRefreshListView)result.findViewById(R.id.directoryList);
emptyTextView = (TextView)result.findViewById(R.id.emptyEventsView);
adapter = new ListViewAdapter(getActivity(), R.layout.listview_item, someList);
listView.setAdapter(adapter);
listView.setEmptyView(emptyTextView);
listView.setOnItemClickListener(this);
listView.setOnRefreshListener(this);
listView.post(new Runnable() {
#Override
public void run() {
listView.setRefreshing();
}
});
return result;
}
Sorry for the long post. Any help would be appreciated.
As ParseQueryAdapter is meant to be used with an Activity - what is the general design idea for using a ParseQueryAdapter for a ListFragment? I want to display a custom list view.
I've tried to use a ParseQueryAdapter with a ListFragment, but the images are not displayed properly. If I use the exact code with an Activity, the images load correctly.
How can you use a ParseQueryAdapterin conjunction with a ListFragment?
I've posted the general code, but the text from the query loads wonderfully in the list, the images however don't always load or when they do..take a LONG time to show up.
<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" >
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#android:id/list"
android:divider="#null"
android:dividerHeight="0px"
/>
</RelativeLayout>
public class PlacesTab extends ListFragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.places_tab, container, false);
mainAdapter = new ParseQueryAdapter<ParseObject>(getActivity(), “Places”);
mainAdapter.setTextKey("name");
mainAdapter.setImageKey(“placeImage");
listView = (ListView) rootView.findViewById(android.R.id.list);
listView.setAdapter(mainAdapter);
mainAdapter.loadObjects();
return rootView;
}
}//end class
I have a fragment class and its layout is in xml. Inside the xml fragment layout is the gridview. I wanted the gridview to show the data.
What happens is that when I run the android app, the app failed to execute/run. It has stopped unexpectedly.
public class FrontPageFragment extends Fragment {
//private ArrayAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final String [] items=new String[]{"Item1","Item2","Item3","Item4"};
ArrayAdapter ad=new ArrayAdapter<String>(this.getActivity().getApplicationContext(),R.layout.frontpage,items);
View fragmentView=getView();
GridView grid=(GridView)fragmentView.findViewById(R.id.forApprovalOrders);
grid.setAdapter(ad);
// Inflate the layout for this fragment
return inflater.inflate(R.layout.frontpage, container, false);
}
=========================================================================
<?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">
<GridView android:id="#+id/forApprovalOrders"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
>
</GridView>
<ExpandableListView android:id="#+id/sampleExpandable" android:layout_height="wrap_content" android:layout_width="match_parent"></ExpandableListView>
</LinearLayout>
i think you want these ad.notifyDataSetChanged();
Might be wrong, but it seems like you are setting the adapter before inflating the layout. This will cause a problem because before you inflate the layout, the gridview doesn't exist and grid.setAdapter(...) will throw a NullPointerException. Try moving the following snippet from the onCreateView(...) to onActivityCreated(...), after calling super.onActivityCreated(...):
final String [] items=new String[]{"Item1","Item2","Item3","Item4"};
ArrayAdapter ad=new ArrayAdapter<String>
(this.getActivity().getApplicationContext(),R.layout.frontpage,items);
View fragmentView=getView();
GridView grid=(GridView)fragmentView.findViewById(R.id.forApprovalOrders);
grid.setAdapter(ad);
Have you tried this:
View fragmentView= inflater.inflate(R.layout.frontpage, container, false);
GridView grid=(GridView)fragmentView.findViewById(R.id.forApprovalOrders);
grid.setAdapter(ad);
// Inflate the layout for this fragment
return fragmentView;
If it's not solved, what is the error message and at what line did it stop while debugging?
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)