Pull-to-Refresh Listview Pull on Empty View - android

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.

Related

headerView does not scroll with the listview Android

I am using a DragSortListView and i want a header which will scroll down and up with the list. I have no idea why the header is not scrolling with the list. I use the listview in a fragment and i added the header like this:
public void onViewCreated(View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
DragSortListView cursListView = (DragSortListView) view.findViewById(R.id.drag_list);
LayoutInflater inflater = (LayoutInflater) Utils.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
titleLayout = inflater.inflate(R.layout.title_row, null);
cursListView.addHeaderView(titleLayout);
setTitle(titleName, titleValue);
cursListView.setAdapter(cursorAdapter);}
setTitle sets the values for the header and Utils.getContext() return the context of the Application.
public void setTitle(String currency, float value) {
((TextView) titleLayout.findViewById(R.id.titleName)).setText(currency);
((EditText) titleLayout.findViewById(R.id.titleValue)).setText(String.valueOf(value));
((EditText) titleLayout.findViewById(R.id.titleValue)).setImeActionLabel(getString(R.string.convert), EditorInfo.IME_ACTION_DONE);
((EditText) titleLayout.findViewById(R.id.titleValue)).setOnEditorActionListener(convertCurrencies);
restartLoader();
}
Why not create the illusion of a header?
<?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="vertical" >
<TextView
android:id="#id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
This way the TextView, in this case, will always stay on top, the ListView can still scroll, which is the desired result if I understand your question correctly.
i think you have first understand what is Header of Footer. Header means that is Always on Top and visible in any Condition same as Footer which is always on bottom and visible.that same concept use for HeaderView and FooterView in listview in android.
So Achive your goal Add one item as header and get it in your Adapterclass getView method and Display it. if there are only one header then at 0 position Your Header available and other position your item available. and it is scroll with your list.
Thats it...

ListView not appearing in fragment

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.

Android: ListView with expanding LinearLayouts as items causes duplicates

I'm trying to write a test application that consists of a few fragments.
One fragment should contain a listView of all music artists from the device.
Each item of this list is a linearlayout starting with a TextView with the artist name and an empty linearlayout under it as follows:
The list is of this layout:
<ListView
android:id="#+id/artistsLists"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
</ListView>
Each item is of the following layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/artistName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:text="" />
<LinearLayout
android:id="#+id/artistsAlbums"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
I'm populating the list using a SimpleCursorAdapter in the following way:
public class MusicTabFragment extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_music_tab,container,false);
Cursor artistsCursor = getActivity().getContentResolver().query(Audio.Artists.EXTERNAL_CONTENT_URI, new String[]{Audio.Artists.ARTIST,Audio.Artists._ID}, null, null,Audio.Artists.ARTIST);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(view.getContext(), R.layout.music_artist_list_item_layout, artistsCursor, new String[]{Audio.Artists.ARTIST},new int[]{R.id.artistName},0 );
ListView lView = (ListView)view.findViewById(R.id.artistsLists);
lView.setAdapter(adapter);
lView.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
((LinearLayout)view.findViewById(R.id.artistsAlbums)).removeAllViews();
Cursor albumsCursor = getActivity().getContentResolver().query(Audio.Artists.Albums.getContentUri("external", ((Cursor)parent.getItemAtPosition(position)).getLong(1)), new String[]{Audio.Albums.ALBUM, Audio.Albums._ID},null,null,null);
LinearLayout artistLayout = (LinearLayout)view.findViewById(R.id.artistsAlbums);
for(albumsCursor.moveToFirst();!albumsCursor.isAfterLast();albumsCursor.moveToNext())
{
View albumView = LayoutInflater.from(view.getContext()).inflate(android.R.layout.simple_list_item_1,artistLayout,false);
((TextView)albumView.findViewById(android.R.id.text1)).setText(albumsCursor.getString(0));
artistLayout.addView(albumView);
}
Log.d("POPULATE","populated again!");
albumsCursor.close();
}
});
return view;
}
}
This works just fine. when i click an artist name, the linearlayout populates with all of this artist album names.
the problem is, that once a linearLayout scrolls out of view, it shows again from the other edge of the view (PacMan Style) as if another list item's linearLayout was populated.
It happens every time the expanded layout goes out of sight. the funny part is that some times when scrolling back up, the linearLayout shows under a different artist name.
example
I'll be glad to hear how should I implement this fragment. But i will also like to know why this behavior is caused.
Thanks,
Maor.
I have found the solution here at stackoverflow.com
It appears that the view shouldn't hold any data, since it is being used for different data when i scroll back and fourth.
I think holding an external data structure to save each virtual view state is not nice programming. is there a way to keep this data anyway? (for this i will be looking now)

Display contents from ListView defined in regular Activity Android

I wanted to create a search view like the one Google uses. For this I created the following XML layout, which basically is a search bar and a button in the upper section of the screen and a ListView at the bottom of it.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayoutSearch"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#FF394952">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<EditText android:layout_height="wrap_content" android:id="#+id/searchTextBar" android:layout_width="wrap_content" android:layout_weight="1">
<requestFocus></requestFocus>
</EditText>
<Button android:layout_height="fill_parent" android:layout_width="wrap_content" android:id="#+id/searchButton" android:text="Buscar"></Button>
</LinearLayout>
<ListView
android:id="#+id/searchResultList"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true"
android:layout_weight="1.0" />
</LinearLayout>
And this is the code of the textViewResource that the ArrayAdapter demands on its constructor:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</TextView>
Now, this is the code of the activity. So far, I just want to display the view with the contents (that's why I'm using a static String array for now).
public class SearchActivity extends Activity{
static final String[] COUNTRIES = new String[] {
"Afghanistan", "Albania", "Algeria"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.searchview);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.list_item, COUNTRIES);
ListView lv = (ListView)this.findViewById(R.id.searchResultList);
lv.setAdapter(adapter);
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
Toast.LENGTH_SHORT).show();
}
});
}
}
However, when I run the activity I see the search bar but it doesn't display the ListView.
I've tried changing the extension of SearchActivity to ListActivity, but the program just crashes when I try to start it. I'm also aware of the existence of the Search Interface, but I just want to see this particular method work.
Why it doesn't display the contents of the ListView? Is there a way to fix this?
Thanks in advance
If you are going to use ListActivity you should be aware that ListActivity already has a ListView instance. You need to call its setListAdapter method to set the adapter for its ListView instead of instantiating your own ListView and setting the adapter on it. You can call getListView to get a handle on ListActvity's ListView and then set the click listener on that.
If you want to extend ListActivity then you must have a ListView with id #android:id/list. Change the id of your ListView, that should fix the crash when extending ListActivity.

How to add a footer in ListView?

I am developing an application,In my application,I am using Listview for displaying data using dom parsing,I want to footer in listview,when i click footer additional more data add to list view,I attached image,i would like that design and process,please refer image1 and imgae2.I mention footer in red rectangle
Fig1-Footer like "More News"
Fig2-Add additional 10 record added in listview
Create a footer view layout consisting of text that you want to set as footer and then try
View footerView = ((LayoutInflater) ActivityContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_layout, null, false);
ListView.addFooterView(footerView);
Layout for footer could be something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="7dip"
android:paddingBottom="7dip"
android:orientation="horizontal"
android:gravity="center">
<LinearLayout
android:id="#+id/footer_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_gravity="center">
<TextView
android:text="#string/footer_text_1"
android:id="#+id/footer_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dip"
android:textStyle="bold"
android:layout_marginRight="5dip" />
</LinearLayout>
</LinearLayout>
The activity class could be:
public class MyListActivty extends ListActivity {
private Context context = null;
private ListView list = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
list = (ListView)findViewById(android.R.id.list);
//code to set adapter to populate list
View footerView = ((LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_layout, null, false);
list.addFooterView(footerView);
}
}
Answers here are a bit outdated. Though the code remains the same there are some changes in the behavior.
public class MyListActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
TextView footerView = (TextView) ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false);
getListView().addFooterView(footerView);
setListAdapter(new ArrayAdapter<String>(this, getResources().getStringArray(R.array.news)));
}
}
Info about addFooterView() method
Add a fixed view to appear at the bottom of the list. If addFooterView() is called more than once, the views will appear in the order they were added. Views added using this call can take focus if they want.
Most of the answers above stress very important point -
addFooterView() must be called before calling setAdapter().This is so ListView can wrap the supplied cursor with one that will also account for header and footer views.
From Kitkat this has changed.
Note: When first introduced, this method could only be called before setting the adapter with setAdapter(ListAdapter). Starting with KITKAT, this method may be called at any time. If the ListView's adapter does not extend HeaderViewListAdapter, it will be wrapped with a supporting instance of WrapperListAdapter.
Documentation
I know this is a very old question, but I googled my way here and found the answer provided not 100% satisfying, because as gcl1 mentioned - this way the footer is not really a footer to the screen - it's just an "add-on" to the list.
Bottom line - for others who may google their way here - I found the following suggestion here: Fixed and always visible footer below ListFragment
Try doing as follows, where the emphasis is on the button (or any footer element) listed first in the XML - and then the list is added as "layout_above":
<RelativeLayout>
<Button android:id="#+id/footer" android:layout_alignParentBottom="true"/>
<ListView android:id="#android:id/list" **android:layout_above**="#id/footer"> <!-- the list -->
</RelativeLayout>
If the ListView is a child of the ListActivity:
getListView().addFooterView(
getLayoutInflater().inflate(R.layout.footer_view, null)
);
(inside onCreate())
The activity in which you want to add listview footer and i have also generate an event on listview footer click.
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list_of_f = (ListView) findViewById(R.id.list_of_f);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.web_view, null); // i have open a webview on the listview footer
RelativeLayout layoutFooter = (RelativeLayout) view.findViewById(R.id.layoutFooter);
list_of_f.addFooterView(view);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg" >
<ImageView
android:id="#+id/dept_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/dept_nav" />
<ListView
android:id="#+id/list_of_f"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/dept_nav"
android:layout_margin="5dp"
android:layout_marginTop="10dp"
android:divider="#null"
android:dividerHeight="0dp"
android:listSelector="#android:color/transparent" >
</ListView>
</RelativeLayout>
In this Question, best answer not work for me. After that i found this method to show listview footer,
LayoutInflater inflater = getLayoutInflater();
ViewGroup footerView = (ViewGroup)inflater.inflate(R.layout.footer_layout,listView,false);
listView.addFooterView(footerView, null, false);
And create new layout call footer_layout
<?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/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Done"
android:textStyle="italic"
android:background="#d6cf55"
android:padding="10dp"/>
</LinearLayout>
If not work refer this article hear
you can use a stackLayout, inside of this layout you can put a list a frame, for example:
<StackLayout VerticalOptions="FillAndExpand">
<ListView ItemsSource="{Binding YourList}"
CachingStrategy="RecycleElement"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Image, Mode=TwoWay}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Frame BackgroundColor="AliceBlue" HorizontalOptions="FillAndExpand">
<Button Text="More"></Button>
</Frame>
</StackLayout>
this is the result:
// adding a footer to list as Log Out
val view: View =
(getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(
R.layout.logout_menu, null, false
)
// footer onClick
view.setOnClickListener {
doLogout()
binding.drawerLayout.close()
}
expandableListView.addFooterView(view)

Categories

Resources