I am learning to use the Hierarch Viewer tool, but meanwhile any hint on why below layout is not rendering correctly is appreciated.
I am trying to render an "html" table view. The content (table body) is rendered correctly with a custom list adapter. This works. But, when I add a textView (text_test below) to use as header, the list is not rendered anymore. I could see the code flow through my adapter (populate view holder, etc), but on screen I only see the Title text, no listView. I used to use FrameLayout (as noted in the comment), but then switched to LinearLayout.
Thanks.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_list_view, container,
false);
ListView lv = (ListView)view.findViewById(R.id.my_list_view_one);
// Tell the list view which view to display when the list is empty
//lv.setEmptyView(getActivity().findViewById(R.id.my_list_view_empty));
// Set up the adapter
mCustomAdapter = new ListAdapterMyType(inflater, new ArrayList<MyType>());
lv.setAdapter(mCustomAdapter);
return view;
}
my_list_view.xml
<?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">
<!-- The frame layout is here since we will be showing either
the empty view or the list view. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/text_test"/>
<ListView
android:id="#+id/my_list_view_one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
<!-- Here is the view to show if the list is emtpy -->
<TextView android:id="#+id/my_list_view_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/list_no_items"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
But, when I add a textView (text_test below) to use as header, the list is not rendered anymore.
The TextView is set to match_parent in both the width and height, so it will fill the entire screen... To put a TextView above your ListView try:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/text_test"/>
<ListView
android:id="#+id/my_list_view_one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
<!-- Here is the view to show if the list is emtpy -->
<TextView android:id="#+id/my_list_view_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/list_no_items"
android:visibility="gone"/>
</LinearLayout>
I removed the outer LinearLayout, since it only had one child it did nothing. I also changed the remaining LinearLayout's orientation to vertical and set the header TextView height to wrap_content.
If you want your custom header to scroll with your ListView, use the addHeaderView() method (before calling setAdapter()) instead of a separate TextView in your layout. This approach will also hide the header when the ListView is empty.
Related
i have an xml layout that i want to use in 2 cases:
1- for listView item in the adapter (without scroll in a row)
2- for another activity (with a scroll)
I've tried to make this layout Scrollable ( scrollView on the parent)
- when it your for listView item ( disacle the scroll effect)
- when it used for the other activity, enable the scrollView
But when i make this solution, i can't have the onClickListner on the listView item.
my xml file: list_messages_fragment_item.xml
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/light_gray_2"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:descendantFocusability="blocksDescendants"
isScrollContainer="false"
>
-- My One chlid LinearLayout containing my content
</ScrollView>
this Xml file is the adapter of my listView: (no need to scroll in this case)
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
vi = inflater.inflate(R.layout.list_messages_fragment_item, null);
....
}
this xml file is used also for an activity layout: (need scroll in this case)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.list_messages_fragment_item);
....
}
i found a solution for what i want.
i use a LinearLayout parent in my xml file.
i create an other layour for the activity: this layout contains a ScrollView, inside i include my xml file that i want to re-use.
the new layout to use in the activity:
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical"
android:scrollbars="none">
<include layout="#layout/list_messages_fragment_item"/>
</ScrollView>
list_messages_fragment_item.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"
android:orientation="vertical"
android:background="#color/light_gray_2"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:descendantFocusability="blocksDescendants"
>
...... my Layout content
</LinearLayout>
I have ViewPager with ListView below it in Linear Layout. Its working fine however when I am try to scroll only ListView scrolls while ViewPager remains static.
This is my XML code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="150dp"
android:isScrollContainer="true" />
<ListView
android:id="#+id/categorylist"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
I want ViewPager also to scroll and move upward rather than remaining static.
#vo12 Add View pager as the header of the list.
And for the error that you are getting.
Remove view pager from that xml:
<ListView
android:id="#+id/categorylist"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
. Create a new View pager in code or inflate a different xml.
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="150dp"
android:isScrollContainer="true" />
And add the header view
View headerView = getLayoutInflater().inflate(R.layout.header_view , null , false);
listView.addHeaderView(headerView);
You were getting an error because your viewpager was attached to LinearLayout and so it's layoutparams were set accordingly but to add it to the list you either need to remove this view from linearlayout and add or add a new one.
Try to add the ViewPager as a header of your listview.
I have a TabHost with several tabs, which content is defined as a FrameLayout, which wraps a TextView, each one of them having a lot of text, more than it can be shown within the screen layout, so I had to enable vertical scrolling for every tab.
The main thing is that those tabs are created dynamically (programatically), so I have to specify all the options this way:
final SoftReference<TabHost> th = new SoftReference<TabHost>((TabHost) ((Activity) globvars.getContext()).findViewById(android.R.id.tabhost));
final TabSpec setContent = th.get().newTabSpec(tag).setIndicator(tabview).setContent(new TabContentFactory() {
public View createTabContent(String tag) {
view.setBackground(globvars.getContext().getResources().getDrawable(R.drawable.rounded_edges));
view.setPadding(25, 25, 25, 25);
view.setTextColor(Color.WHITE);
view.setLines(50);
view.setMaxLines(maxLines);
view.setEllipsize(TextUtils.TruncateAt.START);
view.setHorizontalScrollBarEnabled(false);
view.setVerticalScrollBarEnabled(true);
view.setMovementMethod(new ScrollingMovementMethod());
view.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
view.setVerticalFadingEdgeEnabled(true);
view.setGravity(Gravity.BOTTOM);
view.setOverScrollMode(1);
view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 11);
view.setTypeface(Typeface.MONOSPACE);
return view;
}
});
Using this approach, I can scroll backwards and forwards indeed, but visually the scrollbar is not shown. I'm mean this bar:
Am I missing something? Does the scrollbar have to be defined by a customized drawable by imperative?
Thanks!
------ EDIT (12-31-2013) ------
I've been looking around and still can't find any solution to this. I've tried as many combinations of parameters as I was able to find, but no result. Particularly, I've tried this and also wrapping the FrameLayout within a ScrollView, but instead of showing a scrollbar at the TextView itself, the whole TextView is wrapped within a scrollbar and grows when buffer gets bigger and bigger, that's not what I want.
Any help appreciated!
------ EDIT (01-17-2014) ------
Well, at this point, I can assure I've tried any logical step (well, at least to me) to make this work and still can't! I clarify that I have about 7-8 additional activities and I have no trouble with scrolling in any of them. I just work with TabHost in this one, though. So I'm starting a bounty on this, because that's already endangering my mental sanity.
I'm posting my layout below:
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/fondo_imagen"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/TabContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="99"
android:orientation="vertical">
<TabHost
android:id="#+android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/TabLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Horizontal scrolling for the tab widget -->
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="none">
<TabWidget
android:id="#+android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</HorizontalScrollView>
<FrameLayout
android:id="#+android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp" />
</LinearLayout>
</TabHost>
</LinearLayout>
<!-- Some additional LinearLayouts that don't have anything to do with the tab widget -->
...
</LinearLayout>
------ EDIT (01-19-2014) ------
Ok, based on corsair992's answer, I could finally get this working. My real mistake was assuming that even the method that creates the tab (posted above) receives a TextView as parameter, working with a View in the TabSpec definition would be casting it to the TextView. So indeed, I wasn't aware I was actually setting the scrollbars on a View (didn't know the View class didn't provide a public programatic method to configure scrollbars neither), so I followed corsair992's advice and created a separate layout with this content:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/tabsContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="3dp"
android:background="#drawable/rounded_edges"
android:gravity="bottom"
android:padding="8dp"
android:scrollHorizontally="false"
android:scrollbarStyle="insideOverlay"
android:scrollbars="vertical"
android:textColor="#FFFFFF"
android:textSize="11sp"
android:typeface="monospace"
tools:ignore="SmallSp" />
So now, instead of calling the above method which sets all those attributes to the View, I simply inflate this layout and set the MovementMethod:
final TabSpec setContent = th.get().newTabSpec(tag).setIndicator(tabview).setContent(new TabContentFactory() {
public View createTabContent(String tag) {
// tabs_content is the layout above
final View ll_view = LayoutInflater.from(globvars.getContext()).inflate(R.layout.tabs_content, null);
final TextView view = (TextView) ll_view.findViewById(R.id.tabsContent);
view.setMovementMethod(new ScrollingMovementMethod());
return ll_view;
}
});
It appears that the base View class does not provide a public method for initializing scroll bars if they are not specifically enabled in an XML layout resource. However, there is no reason you can't define your tab content in an XML resource, enable vertical scroll bars by setting the android:scrollbars attribute to vertical, and inflate it from the TabContentFactory dynamically.
Something like this in your case:
public View createTabContent(String tag) {
Activity activity = (Activity) globvars.getContext();
TextView view = (TextView) LayoutInflater.from(activity).inflate(R.layout.mytabcontent,
(ViewGroup) activity.findViewById(android.R.id.tabcontent), false);
view.setMovementMethod(new ScrollingMovementMethod());
view.setText("My Text");
return view;
}
I am trying to design a 3D page curl.
In my mainActivity, I have a viewPager which contains pages to be curled. For each page I have a separate layout file.
In the layout file if i just add a text view like below it is showing up fine:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/PageTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/green"
android:text="VIEW 1" /> -->
But if I wrap the textview inside relative layout, it just shows a white blank screen and textview is not shown.
<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"
tools:context=".DemoActivity" >
<TextView
style="#style/PageTitle"
android:id="#+id/sampletextview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="VIEW 1" />
</RelativeLayout>
Can someone please help me to know why i am not able to use relative layout in my view layout file:
I inflate the view like this:
LayoutInflater inflater = (LayoutInflater) myAppContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view1 = inflater.inflate(mViewIds[0], null);
Try changing the second parameter of the inflate() call from null to the ViewGroup that view1 is added to. Or post the code where you add it (and include the part where you define the LayoutParams).
<TextView
android:id="#android:id/empty"
style="#style/FacebookFont"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/no_result_found"
android:textColor="#color/white" />
this is the xml code for empty view. I am setting empty view as follows:
list.setAdapter(adapter);
list.setEmptyView(findViewById(android.R.id.empty));
I have the items in the listview even then also before listview is populated the empty view is shown.
I don't want that empty view to be shown when listview contains some item.
Please help.
if you are using ListActivity then no need to set the empty view manually. Remove list.setEmptyView(findViewById(android.R.id.empty)); from your code.
Change your layout like below then it's automatically add EmptyView if list has no item:
<?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"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<TextView android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
</LinearLayout>
You have to set the empty view before setting the adapter, if your MainActivity is not extending ListActivity.
Try this
list.setEmptyView(findViewById(android.R.id.empty));
list.setAdapter(adapter);
Sorry for the late answer!
Alternate method: Make your activity extend from ListActivity. And add a textview to your list layout with id android.R.id.empty
Try this
View view = getLayoutInflater() .inflate(<resource id of the empty view>, null);
ViewGroup viewGroup= ( ViewGroup)list.getParent();
viewGroup.addView(view);
list.setEmptyView(view);
list.setAdapter(adapter);
There are some correct answers, however, I think this is the best approach I've found:
View emptyView = getLayoutInflater().inflate(R.layout.empty_list_cart, null);
addContentView(emptyView, listView.getLayoutParams()); // You're using the same params as listView
listView.setEmptyView(emptyView);
listView.setAdapter(adapter);
Whatever #dhawalSodhaParmar has explained is correct. But there is a confusion when you look at the way the answer is put down.
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".SampleActivity">
<ListView
android:id="#+id/list"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_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:divider="#null"
android:dividerHeight="0dp" />
<!-- Empty view is only visible when the list has no items. -->
<TextView
android:id="#+id/empty_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="NO DOCUMENTS AVAILABLE!"
android:textColor="#525252"
android:textAppearance="?android:textAppearanceMedium"
android:visibility="gone"/>
</RelativeLayout>
Suppose if you already have a list view and adapter backing the same with data. And assuming everything is working fine, whoever wants to implement this empty list view screen has to start like below:
Step 1:
Modify the existing Activity XML file which has the list view with the one I have used here. You can use either a Linear Layout or Relative Layout, but preferably Relative because of the flexibility. And a textView like I have written.
Step 2:
Go to your Activity Java file, and after your setContentView
ListView emptyListView = (ListView) findViewById(R.id.list);
// set your adapter here
// set your click listener here
// or whatever else
emptyListView.setEmptyView(findViewById(R.id.empty_text_view));
That's it, now run and you are set!
// first of all create a global variable of Text view
// which is displayed when the list is empty
private TextView mEmptyStateTextView;
//then in onCreate(Bundle savedInstanceState)
/Setting empty text view
mEmptyStateTextView=(TextView) findViewById(R.id.emptyview);
view.setEmptyView(mEmptyStateTextView);
//then in onLoadfinished method
mEmptyStateTextView.setText(R.string.no_earthquakes);