Android PullToRefesh library customize loading pulling/refreshing image - android

I am using com.handmark.pulltorefresh.library.PullToRefreshListView. By default it shows:
But I want pulltorefresh images/desing as following:
Here is xml i am using:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="#+id/lv_Inbox"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:divider="#19000000"
android:dividerHeight="4dp"
android:fadingEdge="none"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:scrollbars="none"
android:smoothScrollbar="true"
ptr:ptrAnimationStyle="flip"/>
<ProgressBar
android:id="#+id/progress_LoadingList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="visible" />
<TextView
android:id="#+id/lbl_NoMessagesFound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="gone" />
</RelativeLayout>

The animation style controls how the Pull-to-Refresh functionality is presented to the user. The different options are:
Rotate (default)
Flip
Customizing icon and custom labels
And you want flip,So in your xml view
<com.handmark.pulltorefresh.library.PullToRefreshListView
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:id="#+id/pull_to_refresh_listview"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
ptr:ptrAnimationStyle="rotate"
/>
Change
ptr:ptrAnimationStyle="rotate"
to
ptr:ptrAnimationStyle="flip"
And add xmlns:ptr="http://schemas.android.com/apk/res-auto" in com.handmark.pulltorefresh.library.PullToRefreshListView tag as
<com.handmark.pulltorefresh.library.PullToRefreshListView
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:id="#+id/lv_Inbox"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:divider="#19000000"
android:dividerHeight="4dp"
android:fadingEdge="none"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:scrollbars="none"
android:smoothScrollbar="true"
ptr:ptrAnimationStyle="flip"/>
For more info see android-pull-to-refresh Customization

An advanced pull to refresh will help you to provide modern approach in your app.
It is very smooth and easy to implement. And it will support for the lower versions also (from v2.3). The below screen shot will recall the new kind of refresh.
UI part
Create an Android from your eclipse or Android studio.
In your activity layout add the SwipeRefreshLayout.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="#string/hello_world"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"/>
</ScrollView>
Note : It has only View inside the layout. Add the scrollView inside the SwipeRefresh layout to support pull to refresh. For ListView and GridView no need to add ScrollView inside SwipeRefreshLayout.
code part
Add the following lines in onCreate method of your Activity.
public class SwipeActivity extends Activity implements OnRefreshListener {
SwipeRefreshLayout swipeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light);
}
#Override
public void onRefresh() {
// TODO Auto-generated method stub
new Handler().postDelayed(new Runnable() {
#Override public void run() {
swipeLayout.setRefreshing(false);
}
}, 5000);
}
}
swipeLayout.setOnRefreshListener(this); sets Refresh listener for your layout.
Loading color schemes are adding using
swipeLayout.setColorScheme(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light);
To stop the loading progress swipeLayout.setRefreshing(false);.
Thats it. Run your appplicaton you also did the new pull to refresh.
SWIPE TO REFRESH WITH LISTVIEW
Here I add an example of pull to refresh with listview. Then you will know how easy it is to integrate.
Create a new Activity in your application, add the listview in your SwipeRefreshLayout.
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
Declare and initialze variables for listview, adapter, String array for list items. Below codes will add the list items from array when you do pull to refresh.
public class SwipeActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.swipe, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment implements OnRefreshListener {
SwipeRefreshLayout swipeLayout;
ListView listView;
ArrayAdapter adapter;
ArrayList< String> arrayList;
String [] array = new String[]{"Apple","Batman","captain America","darkknight"};
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_swipe, container, false);
swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
listView= (ListView) rootView.findViewById(R.id.listview);
adapter = new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1, appendData());
listView.setAdapter(adapter);
return rootView;
}
#Override
public void onRefresh() {
// TODO Auto-generated method stub
new Handler().postDelayed(new Runnable() {
#Override public void run() {
appendData();
adapter.notifyDataSetChanged();
swipeLayout.setRefreshing(false);
}
}, 5000);
}
private ArrayList appendData(){
if(arrayList==null)
arrayList = new ArrayList();
for (String items : array) {
arrayList.add(items);
}
return arrayList;
}
}
}
Note: I have used appcompat library to support the Actionbar for lower versions. So My Activity extends ActionBarActivity. In updated ADT version of eclipse and studio, your application will be created with fragment concepts. So application is created with instant fragment concepts.
I guess you like this example. Try it yourself and get practiced.
Happy coding :-).
And resultant screen, see this:
And for your existing program, use this link

Related

How to add a header to a listView which is inside SwipeRefreshLayout?

Background
I've noticed an issue (link here) when adding a header view inside a ListView, in case the ListViewis inside a SwipeRefreshLayout.
The problem
The issue is that if the header view is partially visible, and you scroll up, you will see the circular view of the SwipeRefreshLayout.
You can check the link above to see a video of what I'm talking about.
Sample code
Here's how to reproduce this issue (you can check the link above in case you don't want to copy-paste) :
MainActivity.java
public class MainActivity extends ActionBarActivity
{
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listView=(ListView)findViewById(android.R.id.list);
final TextView tv=new TextView(this);
tv.setText("a very large header view");
tv.setTextSize(70);
listView.addHeaderView(tv);
final SwipeRefreshLayout swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.swipeToRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(new OnRefreshListener()
{
#Override
public void onRefresh()
{
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
swipeRefreshLayout.setRefreshing(false);
}
},1000);
}
});
final ArrayList<String> arrayList=new ArrayList<String>();
for(int i=0;i<1000;++i)
arrayList.add(Integer.toString(i));
listView.setAdapter(new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,arrayList));
}
}
res/layout/activity_main.xml
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeToRefreshLayout"
android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="#android:color/transparent"
android:fastScrollEnabled="true"
android:footerDividersEnabled="true"
android:headerDividersEnabled="true"
android:paddingEnd="4dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingStart="4dp"
android:scrollingCache="false"
android:smoothScrollbar="false"
android:textFilterEnabled="true"/>
</android.support.v4.widget.SwipeRefreshLayout>
The question
Is there a way to solve this problem?
I guess I could use multi-types for the listView , but is there maybe another solution that is more elegant, simple or better in any other way?
Very similar to Android issue 78375.
Try to override SwipeRefreshLayout#canChildScrollUp
#Override
public boolean canChildScrollUp() {
View target = getChildAt(0);
if (target instanceof AbsListView) {
final AbsListView absListView = (AbsListView) target;
return absListView.getChildCount() > 0
&& (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
.getTop() < absListView.getPaddingTop());
} else {
return target.getScrollY() > 0;
}
}
EDIT: It seems it occurs even if I use multi-type items for the ListView. Later I've discovered that it just always occur for the first item on the listView.
If the first item is large enough, it will be easy to reproduce.
So, for now, there is a simple workaround:
Before using the listview in any way, first add an empty view as a header view, and never remove it:
listView.addHeaderView(new View(this));
This way, as the view is practically invisible, the bug won't be shown to the user.
This is just a workaround, but I think the best thing should be to fix this issue.

SwipeRefreshLayout not working

I'm using SwipeRefreshListener from the support libraries. I am calling setRefresh from onPreExecute and onPostExecute of my AsyncTask. However, nothing changes, there is no animation. Is there something that I'm missing? Are there certain setup parameters I need to set in order for it to work properly?
This has worked for me, see more here: http://antonioleiva.com/swiperefreshlayout/
SwipeRefreshLayout: The layout
you only need to decorate the swipable content (probable the whole layout) with this new layout. This view must be scrollable, such a ScrollView or a ListView. As a simple example:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="#string/hello_world"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"/>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
The code
We just need to get the layout, and assign some colours and the listener. The refreshing listener is a post delayed handler.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
#Override public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override public void run() {
swipeLayout.setRefreshing(false);
}
}, 5000);
}
//Please check this answers it hepls me :
//SwipeRefreshLayout setRefreshing() not showing indicator initially
//especially this
mSwipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});

ListView set contents gravity to right

I have a Fragment in which there is a ListView.
The ListView is populated using a simple ArrayAdapter which its code is below.
I want the ListView to show it's content from RIGHT to LEFT.
(I want each row of ListView to set its text to its right)
The gravity set to right seems to do nothing.
I tried a couple of solutions suggested in here but I don't know why no matter what change I make I don't see any difference.
I have changed width of ListView and Layouts to match_parent, fill_parent, wrap_content... nothing changed.
My Activity xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context="com..SearchResultListActivity"
tools:ignore="MergeRootFrame"/>
My Fragment xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_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"
android:layout_gravity="right"
android:gravity="right"
android:orientation="vertical"
tools:context="com.***.SearchResultListActivity$PlaceholderFragment" >
<ListView
android:id="#+id/listViewSearchResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right">
</ListView>
</LinearLayout>
My Activity Class:
public class SearchResultListActivity extends ActionBarActivity {
//LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
//ArrayList<String> listItems=new ArrayList<String>();
//DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
//ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result_list);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search_result_list, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
String[] array = new String[] {"cat", "dog", "mouse"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, array);
ListView listView = (ListView) getActivity().findViewById(R.id.listViewSearchResult);
listView.setAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_search_result_list, container, false);
return rootView;
}
}
}
You are using the android list item layout, that's why you are not seeing the content correctly, also because you have changed the gravity of the ListView itself, not its content. You should set the gravity of the items, and they must be declared in a new layout file with a custom adapter.
First of all remove the android:layout_gravity="right" from your Fragment xml layout, it won't be needed anymore.
Also your ListView width must be set to match_parent.
Change your Fragment.xml layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_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"
android:orientation="vertical"
tools:context="com.***.SearchResultListActivity$PlaceholderFragment" >
<ListView
android:id="#+id/listViewSearchResult"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Now you must create a new layout to represent the items of your ListView.
1. Create a list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_item_row"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="right"
android:padding="10dp">
<TextView android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:textStyle="bold"
android:textSize="22dp"
android:textColor="#000000"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp" />
</LinearLayout>
As you can see, we set the layout_gravity of the item in this layout, this way the content of your Listview will have this behavior, to be in the right of the ListView.
2. Create custom array adapter class as inner class
Also you must create a custom Adapter to inflate the layout and set the values correctly. This is how your Activity should look with the custom array adapter as inner class
public class SearchResultListActivity extends ActionBarActivity {
//LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS
//ArrayList<String> listItems=new ArrayList<String>();
//DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW
//ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result_list);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search_result_list, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
String[] array = new String[] {"cat", "dog", "mouse"};
// Here we initialize the custom array adapter sending the proper values to the constructor
MyArrayAdapter adapter = new MyArrayAdapter(getActivity(), R.layout.list_item, array);
ListView listView = (ListView) getActivity().findViewById(R.id.listViewSearchResult);
// Here we set the custom adapter to the Listview
listView.setAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_search_result_list, container, false);
return rootView;
}
}
// This is the custom adapter class where you will manage the behavior of your ListView content
public class MyArrayAdapter extends MyArrayAdapter<String>{
Context context;
int layoutResourceId; // This is the layout you created for the list items
String data[] = null; // the array with the data to populate the listview
public MyArrayAdapter(Context context, int layoutResourceId, String[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
// Here we inflate the list item layout to load its views (the TextView)
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
// Now we can get the TextView from the layout
TextView txtTitle = (TextView)row.findViewById(R.id.txtTitle);
// Here we set the value from a specific position in the array
txtTitle.setText(data[position]);
return row;
}
}
}
3. Initialize your adapter
Now you must initialize your adapter based on the custom adapter you created before, like this.
MyArrayAdapter adapter = new MyArrayAdapter(getActivity(), R.layout.list_item, array);
As you can see here we send the custom list_item.xml layout and the array with the data you want to populate also the context on the constructor.
4. Set the adapter to your listview
Now you must set the adapter you created before to your ListView
listView.setAdapter(adapter);
Let me know if you have more doubts.
Hope it helps you.
You have changed the gravity of the ListView container but not the rows it contains as I assume you wanted to.
It's a little unclear whether you want right aligned text or text that gets populted from the right to the left. Either way the solution is the same.
The best solution would be to copy the code from android.R.layout.simple_list_item_1 into your own layout and change the properties of the TextView in there. (Ensure that you keep the View's id the same unless you want to change more of your Adapter code.)
You can find the built-in layouts at <android-sdk-root>/platforms/<version>/data/res/layout/.
Then load your adapter with:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getActivity(),
R.layout.my_simple_list_item, // use your layout
array);
The v19 simple_list_item_1 for reference:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>

Listview as a detail fragment in master/detail view

Am creating a master/detail fragment from this link. This works fine, now here instead of textview in detail fragment class i would like to implement listviews, (ie) i would like to display the details of the masterview as a child listview, hence i tried
detail.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:id="#+id/listview1"
/>"
<ListView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:id="#+id/listview2"
/>"
</LinearLayout>
and in my detailFragment class
public class DetailFragment1 extends ListFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] values = new String[] { "1", "2", "3",
"4" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
}
My problem is child listview is displaying at initial stage but i want to display this listview when i click the first row of master page.Am new to fragments, so help me in achieving this. Thanks in advance..
Create a CallBack interface:
public interface Callbacks {
public void onItemSelected(long id);
}
Let the fragment inplement it:
public class DetailFragment1 extends ListFragment implements CallBacks {
In the ListFragment OnListitemClick:
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
mCallbacks.onItemSelected(id);
}
In the Activity:
Public class MyActivity extends FragmentActivity implements Callbacks {
#Override
public void onItemSelected(long id) {
// Replace the detail fragment with the corresponding item selected in the list
}
Instead of doing like this, you can design a layout which contains ListView as master and frameLayout container. In frameLayout container, you can dynamically inflate layout, which is designed in such a way that you can have child listview and details view.
<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:orientation="horizontal"
tools:context=".NavigationActivity" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#color/strip_background"
android:layout_weight="1"
android:orientation="vertical" >
<ListView
android:id="#+id/nav_lv_transactions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" >
</ListView>
</LinearLayout>
<FrameLayout
android:id="#+id/nav_fl_frag_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="14"
android:background="#android:color/darker_gray" >
</FrameLayout>
</LinearLayout>
In onclick listerner put this code,
Bundle arguments = new Bundle();
arguments.putString(ARG_ITEM_ID,
"Some Name");
MyClassFragment newFragment = new MyClassFragment();
newFragment.setArguments(arguments);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.nav_fl_frag_container, newFragment);
transaction.commit();
Try this. It will work

Support ListFragment issue

I'm currently using a ListFragment together with an ExpandableListView to show some data backed by a SimpleCursorTreeAdapter. Everything works fine, but I recently switched to the support.v4 package, to make use of the ViewPager class to swipe between tabs. Swiping and all the other classes that now use the support.v4.Fragment work fine, but my ListFragment has stopped working.
There are no exceptions thrown, but the ListFragment simply doesn't show any items.
This is the code for the ListFragment:
public class VisuTextFragment extends ListFragment {
private Storage mStorage;
private int mFilterSensortype;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mStorage = Storage.newSQLiteDatabase(getActivity());
mFilterSensortype = -1;
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.l_visu_text, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fillData();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.textvis, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_filter:
final Dialog dialog = new Dialog(getActivity());
dialog.setTitle("Filter by sensor type");
dialog.setContentView(R.layout.l_dialog_filter);
Button ok = (Button) dialog.findViewById(R.id.filter_ok);
ok.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int filter = Integer.parseInt(((EditText) dialog.findViewById(R.id.et_filter)).getText().toString());
mFilterSensortype = filter;
fillData();
dialog.dismiss();
}
});
Button cancel = (Button) dialog.findViewById(R.id.filter_cancel);
cancel.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.cancel();
}
});
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dialog.show();
break;
}
return true;
}
#Override
public void onResume() {
super.onResume();
fillData();
}
public void fillData() {
Log.d("VisuTextFragment", "fillData()");
Cursor cursor;
if (mFilterSensortype == -1)
cursor = mStorage.queryAllAsCursor();
else
cursor = mStorage.query(mFilterSensortype);
TextVisCursorAdapter adapter = new TextVisCursorAdapter(
getActivity(),
cursor,
R.layout.l_visu_text_group,
new String[] { Storage.ELEMENT_ID, Storage.ELEMENT_ENTRIES_DATE, Storage.ELEMENT_ENTRIES_LATITUDE, Storage.ELEMENT_ENTRIES_LONGITUDE, Storage.ELEMENT_ENTRIES_SENSORTYPE },
new int[] { R.id.id, R.id.date, R.id.latitude, R.id.longitude, R.id.sensortype },
R.layout.l_visu_text_child,
new String[] { Storage.ELEMENT_MEASUREMENTS_VALUE },
new int[] { R.id.value });
ListView lv = (ListView) getListView();
ExpandableListView elv = (ExpandableListView) lv;
elv.setGroupIndicator(null);
elv.setAdapter(adapter);
}
}
And this is the layout that I'm using (don't know if that helps):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/id"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="#string/date"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="#string/latitude"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="#string/longitude"/>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/sensortype"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ExpandableListView android:id="#+id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:transcriptMode="normal"/>
<TextView android:id="#+id/android:empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/no_entries"/>
</LinearLayout>
</LinearLayout>
Just FYI: The TextView's in the layout file are shown, but the list itself is just missing. Not even the TextView for an empty list is shown.
Hope you can help.
EDIT: I have checked for the ExpandableListView's width and height via their corresponding methods and both return a value of 0. Its getCount() method returns 347. So the View definitely exists and is filled properly, but it is for some weird reason just not drawn to the screen.
EDIT2: Ok I fixed the problem. The problem was that the LinearLayout that hosted the TextViews on top of the actual list had its layout_height attribute set to fill_parent, which strangely was no issue for the non-support version as well as the composer in eclipse, since they both worked that way and I didn't even notice that it was set to fill_parent.
getListView() in a ListFragment is specifically looking for a listview id of #id/android:list. I'm not sure that adding the "+" in there like you did would have an effect or not, but it's the first thing I would try.
You also note you switched to the support library... did you switch all the appropriate method calls? For example, instead of getFragmentManager you would need to use getSupportFragmentManager and instead of using an Activity to control the fragments, you would need to use FragmentActivity, etc.
I think that that its butter to use android:id="#android:id/list" instead of android:id="#+id/android:list", also, in your case its really useless to extend ListFragment, just use Fragment and use findViewById for your expandableList.
Can you change:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
to:
public void onActivityCreated(Bundle aSavedInstanceState) {
super.onActivityCreated(aSavedInstanceState);
fillData();
}
make sure that your fillData method is called.
Ok I fixed the problem. The problem was that the LinearLayout that hosted the TextViews on top of the actual list had its layout_height attribute set to fill_parent, which strangely was no issue for the non-support version as well as the composer in eclipse, since they both worked that way and I didn't even notice that it was set to fill_parent.

Categories

Resources