Android: ListFragment display blank space - android

I have a ListView (inside a ListFragment) loading data with the help of a LoaderManager, to which I attach a headerView and a footerView. My problem is that after doing that, it is displaying a lot of blank space (like almost an entire screen) after the footer is displayed.
Some code from my ListFragment:
public class NewsDetailsFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getArguments().containsKey(Const.ARG_ITEM_ID)) {
mId = getArguments().getLong(Const.ARG_ITEM_ID);
getLoaderManager().initLoader(NEWS_DETAILS_LOADER_ID, null, this);
getLoaderManager().initLoader(COMMENTS_LOADER_ID, null, this);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mCommentsAdapter = new CommentsListAdapter(getActivity(), null, 0);
View rootView = inflater.inflate(R.layout.frag_news_details_comments,
container, false);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mHeaderView = LayoutInflater.from(getActivity()).inflate(
R.layout.header, getListView(), false);
mFooterView = LayoutInflater.from(getActivity()).inflate(
R.layout.footer, getListView(), false);
setUI();
setAction();
if (mHeaderView != null) {
getListView().addHeaderView(mHeaderView);
}
if (mFooterView != null) {
getListView().addFooterView(mFooterView);
}
setListAdapter(mCommentsAdapter);
}
Obviously, this is not the entire code from my ListFragment class, but the other stuff is mostly related to how the data is being manipulated (Loader Callbacks and others). If there is a need to add full code in order to be able to get the correct answer, I will add it on demand.
As for a general idea of how the screen should look like, the header displays some data about the article (which contains a bunch of TextViews, ImageViews and a Webview), the ListView displays comments on this article (if there are any), and the footer displays a form with writing a comment.
LE: This is how it looks like:
LE2: This screenshot shows how headerView and footerView are limited.
headerView ends at "0 comments on this post:" and after that comes the footerView. In between these two, should be displayed the list of comments (if there are any)
LE3: To make myself even more clear: I will display the wrong (red), and right (green) way it should be displayed.

Turns out I had this background on footerView (the same of the ListView), just to test if everything looked fine, with textColor and stuff, and I forgot to remove it afterwards. Then it took its height, which was larger than the form in the footer, thus creating the empty space. Sry to have bothered your eyes with such stupidity.

Related

TextView forgets its value after tab switching

I've setup a tabhHost in my program with 3 tabs each with a fragment in its content that contains a textView. I've set a button in app that is supposed to update the content of every tab. However the problem i am now facing is that if i change a tab its content gets forgotten and new tab has no value aswell unless i click the button again. Each tab content has a different class but in each of them the class just returns the view with textview in it. I assumed that the values reset on each view inflate however i cannot find a reasonable way to make it work as i intend to it.
Here is the part of the code with the method ran by my button:
public void getNum(View view) {
proteinNeeded = weightNum.getValue() * FirstActivity.weightMultiplier;
carbohydrateNeeded = weightNum.getValue() * 5;
switch (weightMultiplier) {
case 2: {
resultTxt = String.format("Zapotrzebowanie:%nBiałko - %dg.%nWęglowodany - %dg.%n",
FirstActivity.proteinNeeded, FirstActivity.carbohydrateNeeded);
FragmentTab.tv.setText(resultTxt);
FragmentTab2.dietTxt = String.format("text1");
FragmentTab2.tv.setText(FragmentTab2.dietTxt);
FragmentTab3.foodTxt = String.format("text2");
FragmentTab3.tv.setText(FragmentTab3.foodTxt);....
And here is the code from FragmentTab.java, each tab has more or less same code so i'll post only this one for now:
public class FragmentTab extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static View v;
public static TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_layout, container, false);
tv = (TextView) v.findViewById(R.id.textResult);
if (tv != null) {
tv.setText("nothing has been input yet");
}
return v;
}
}
TL;DR - How do I save my values in textView in such a way that if my text gets updated it won't revert to default values after the view gets refreshed?
An option to solve your problem is to use SQLite Database to save your data, and fetch it from database whenever you return to that tab.
You can refer to this link. Saving Data in SQL Databases.
For other android storage options, refer to this series of videos. Android Data Storage Options.

Why my ViewPager is so slow?

Inside the dialogFragment I have viewPager with two pages. Every page contains a custom adapter. One adapter with list of spinners, other adapter with list of EditTexts. ViewPager adds adapters fine.
public class PageFragment extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pagefragment_newprod, null);
LinearLayout ll=(LinearLayout) view.findViewById(R.id.tvLL);
ListView listView=new ListView(getActivity());
ll.addView(listView);
if (pageNumber==0){
dropDownAdapter=new DropDownAdapter(getActivity(), fillListAdapter);
listView.setAdapter(dropDownAdapter);
} else if (pageNumber==1){
boxAdapter = new BoxAdapter(getActivity(), filledFields);
listView.setAdapter(boxAdapter);
}
return view;
}
}
But it works to slow! Current Adapter (I mean at the curren page) create views every milisecond! Look at this:
public class BoxAdapter extends BaseAdapter{
...
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (view == null) {
view = lInflater.inflate(R.layout.addproduct_item, parent, false);
}
Log.d(LOG_TAG, "====As I said every milisecond...======");
EditText editText = (EditText) view.findViewById(R.id.addProductEditText);
editText.setText(p.value);
return view;
}
}
Even when I focused the EditText this Log.d write messages every milisecond!
Besides that, adapter at the next page works too. I have other Log.d at the other adapter getView and it works when I used different page's adapter!
Please help me to understand what is wrong...(
The question has already been solved in the comments. The solution for the OP was apparently to remove complex fragments and their adapter. However, I also had complex fragments in a tab layout with a ViewPager, and the following solution fixed the slow paging problem:
viewPager.setOffscreenPageLimit(2);
The 2 will keep two pages away from the current page in memory. This was enough for me because I had three tabs. Be careful about keeping too many pages in memory, though. See the documentation.

Show empty view for ArrayAdapter in Android

I've got a ListView in my application that's rendered in a ListFragment's onActivityCreated()using setListAdapter(). Passed in to this setListAdapter()are my implementation of ArrayAdapter. At some times this adapter can be empty, and that's fine, but at those moments I would like to show a message in the list telling that there are no items, instead of just an empty view. However I don't really know how to achieve this, as for I have researched most people to show lists in a ListActivityand by doing that you can setEmptyView() but this doesn't seem doable when using a ListFragment. Another way of doing this was to change view in the ListFragment if the ArrayAdapter has no item's in it, then change view to another showing the message, but this seems to me a bit hacky.
Whats really the proper way of doing what I want to achieve?
Tried to setEmptyView() to my ListView but that didn't work either, see code on how views are inflated in my ListFragment:
public class MyFragment extends ListFragment {
#SuppressLint("InflateParams")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ListView listView = (ListView) inflater.inflate(R.layout.my_list, null);
listView.setEmptyView(inflater.inflate(R.layout.list_items_missing, null));
return listView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
MyItemArrayAdapter adapter = new MyItemArrayAdapter(getActivity());
// Populate adapter with items...
setListAdapter(adapter);
}
}
Shouldn't this result in the empty view beeing shown if no items exists in my adapter?
1) Try putting backgroundImage for ListView inside xml. If no item, show backgroundImage, if there is item, put background color.
2) You can also do what as #kgandroid suggested and here, setEmptyView() which you set custom view.
Example:
Another:
You can customize your adapter to show the layout R.layout.list_items_missing when (item == null) instead of inflating the normal custom list item layout that you implement.
Something like this:
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder; //asuming you have this in your custom adapter
if (convertView == null) {
holder = new ViewHolder();
if(MyItemArrayList.get(position)!=null)
{
convertView = this.inflater.inflate(R.layout.layout_list_item,
parent, false);
else
{
convertView = this.inflater.inflate(R.layout.list_items_missing,
parent, false);
}
//the rest of the adapter logic
}

Android: Display two ListViews via Fragments using Fragmenttransaction

For my app, I'm trying to show a list, and as soon as this list ends, the second one shall begin. The Lists are being displayed using a ListAdapter, which again is part of a fragment. Everything works very well, the lists appear correctly, but I can't figure out a way to put one list under the other. I thought this shouldn't be all too hard.
Summary:
What I have:
A FragmentPagerAdapter with 3 Fragments
Two Fragments, which contain one ListView each
My searches:
Apart from multiple searches on this site, this guy came closest to what I'm seeking:
This guy here Fragmenttransaction in 1 tab of a Fragmentpageradapterhas had the same problem, but it wasn't satisfyingly answered, so I thought I can make a valid question here.
My question:
How can I place two ListViews in one Fragment? The big deal is that for example if the first ListView is bigger than the screen, I don't want the second ListView to show up before the first is completely scrolled down.
Current output:
Currently, both ListViews are in the same position, meaning that one ListView is on top of the other, making both unreadable
I thought that I can maybe use a specified layout for the FragmentTransaction. But I just can't figure out how.
This is the Fragment where I combine my top and bottom ListViews
public class LeaguePageTransactionsAdapter extends Fragment{
Global global_var;
ListView list, list_flat;
List <League> leagues = null, leaguesFlat = null;
ListAdapter adapter = null, adapter_flat = null;
View rootView;
FragmentTransaction fragmentTransaction;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.league_page, container, false);
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(rootView.getId(), new LeaguePageTop(), "TopFragment");
fragmentTransaction.add(rootView.getId(), new LeaguePageBottom(), "BottomFragment");
fragmentTransaction.commit();
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
}
}
This is corresponding the xml layout file.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
This is one of my two ListViews
public class LeaguePageTop extends Fragment{
ListView list;
List <League> leagues = null;
ListAdapter adapter = null;
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.league_page_top, container, false);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
list = (ListView) rootView.findViewById(R.id.listView1);
try {
leagues = Leagues_Parser.parse(getActivity().getAssets().open("league_raw.xml"), 0);
} catch (IOException e) {
e.printStackTrace();
}
adapter = new LeagueAdapter (getActivity(), R.layout.list_row, leagues);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Global.mViewPager.setCurrentItem(1, true);
}
});
}
}
This is the corresponding xml file
<?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"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
Thank you very much for reading and thinking about it!
The reason is because you have set the LinearLayout in the XML file you have shown to match_parent which will occupy all available space and then comes your next ListView with it's own LinearLayout (which I presume is set to match_parent as well) and hence there is no space for it to display. FrameLayout and LinearLayout follows an eldest child first approach meaning that the first layout occupies as much space as it requests. Set the LinearLayout you have to wrap_content and I think that should solve your fragment.
Firstly use a view filpper.you can load your first list view in fragment and in your adapterview on item click listener you can flip view by flipper.setdisplayedchild(1) which will show your desired second list.

setText in a ListFragment

I'm a beginner at Android programming and I was wondering if you could help me out.
I have a ListFragment:
public class AdvertFrag extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>
that I'm populating from a database using a loaderManager. This works fine and displays details of adverts, but I would like to do some calculations (work out distance via longitude and latitude) and then have the distance to the shops location displayed on each AdvertFrag.
I have looked into using setText() on a TextView in a fragment and have read you should allow the onCreateView method to be called first so a view is present. I have tried the below code:
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
view = inflater.inflate(R.layout.row, container, false);
if(view == null)
{
Log.i("TEST","null");
}
else
{
distance = (TextView) view.findViewById(R.id.distance);
distance.setText("the distance will go here");
}
return view;
}
But get the error that "Your content must have a ListView whose id attribute is android.R.id.list. Allowing the OnCreateView to just call:
return super.onCreateView(inflater, container, savedInstanceState);
works fine.
So my question is, what am I doing wrong? and how do I get setText working in a ListActivity? Or am i going at it in totally the wrong way?
Addition info if its useful:
My row.xml, just has the text views that are populated by the loader and the additional textview for the distance.
I have a fragmentActivity that has the fragment in its XML, like so:
<fragment
...
android:name="com.example.goclub.AdvertFrag"
.../>
Like user113215 said onCreateView() of the ListFragment is not a place to change widgets inside the list items. You will have to create a custom CursorAdapter for that assuming that you are using one. You can find a nice tutorial about this here. Basically it extends a SimpleCursorAdapter and makes changes in the bindView method.

Categories

Resources