I want to create a layout like this:
I think the ScrollView is necessary, maybe like this:
<RelativeLayout>
<RelativeLayout id="fixed">
</RelativeLayout>
<ScrollView>
<RelativeLayout>
<Button...
<ListView....
<Button...
</RelatievLayout>
</ScrollView>
</RelativeLayout>
But it seems that add a ListView inside a ScrollView is not good idea.
Any idea to make it?
BTW, there are not only Button1 and Button2 outside the listview, there are more views, so I do not think add the views as foot or head is a good idea.
This is xml code
<?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" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout android:id="#+id/rlt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
</RelativeLayout>
Java code
LinearLayout llt = (LinearLayout)findViewById(R.id.rlt);
for(int i=0;i<12;i++)
{
final int k =i;
LinearLayout ll = new LinearLayout(this);
ll.setId(i);
ll.setOrientation(LinearLayout.VERTICAL);
TextView tv = new TextView(this);
tv.setText(" name:"+i);
ll.addView(tv);
ll.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
System.out.println("This is the printed text no"+k);
}
});
//ll.setBackgroundColor(Color.BLACK);
llt.addView(ll);
}
You can create your own ListView like this
First idea (not recommanded): Adding a ListView inside a ScrollView is a bad idea, because both are scrollable by default. You could use a LinearLayout instead of the ListView and create a custom onClickListener for the items.
<Scrollview>
<Button.../>
<LinearLayout>
<items.../>
</LinearLayout>
</Scrollview>
Second idea (recommanded) is to go with one ListView and create a custom Adapter extending BaseAdapter returning the Views for each row and holding the data. This means adding your Buttons and Items to the ListView and create a custom OnClickListener and Adapter to hold you Model. This Is the way I have used and I would do it again this way.
I your Adapter, you will need to Override:
getViewTypeCount - number of types of different row-layouts.
getItemViewType the type of the row.
getView returning the view for a position, here you need to inflate the layout and set the data.
This is a related question how to create a ListView with different types of rows.
Related
I have a simple layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:padding="15dp">
<ScrollView 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="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/scrollLayout">
</LinearLayout>
</ScrollView>
</RelativeLayout>
Now, I inflate the outer RelativeLayout to retrieve the inner LinearLayout to put items in it.
RelativeLayout relative = (RelativeLayout) LayoutInflater.from(activity).inflate(R.layout.gradient_pick_view, null);
LinearLayout view = (LinearLayout) relative.findViewById(R.id.scrollLayout);
After that I created a method to add some buttons to it:
for(int i=0;i<10;i++){
LinearLayout wrapper = (LinearLayout) LayoutInflater.from(activity).inflate(R.layout.button_wrapper, null);
Button button = (Button)wrapper .findViewById(R.id.button);
view.addView(layout);
}
Everything works fine, but it doesn't scroll.
What am I doing wrong here?
Here's the screenshot (displaying 7 of 10 buttons):
I forgot to mention - I'm using a MaterialDialog library and add this RelativeLayout as a custom view to a dialog.
Try to set the following attribute to your scrollview,
android:fillViewport="true"
above attribute is used to make your scrollview to use entire screen of your application.
I had a false parameter passed to a customView in a MaterialDialog.
dialog = new MaterialDialog.Builder(activity)
.title(R.string.about)
.customView(view, true)
.positiveText(R.string.changing_fragments)
.show();
As doc says:
If wrapInScrollView is true, then the library will place your custom view inside of a ScrollView for you. This allows users to scroll your custom view if necessary (small screens, long content, etc.). However, there are cases when you don't want that behavior. This mostly consists of cases when you'd have a ScrollView in your custom layout, including ListViews, RecyclerViews, WebViews, GridViews, etc. The sample project contains examples of using both true and false for this parameter.
Now it's working.
I'm new on android programmation. I want to achieve a simple layout with elements side by side inside a scrollview. The idea is to process a single element per time with image and text, letting the layout choose when its the right time for the carriage return, in dependence of the screen resolution. I tried every type of layout, but no one seems to be suitable for my purpose. Particulary with Relative Layout elements are overlapped, instead what I need is an spatial append. Before to try a workaroud (for example adding more element in a row inside a linear layout) i would to know if exists a more natural solution.
(source: youth-stories.com)
I create an example activity to try the solutions:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RelativeLayout container = (RelativeLayout)findViewById(R.id.container);
for(int i=0; i < 100; i++)
{
final Button button = new Button(this);
button.setText("sda"+i);
button.setId(i);
container.addView(button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
container.removeView(button);
}
});
}
}
}
<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"
android:padding="0dp"
android:id="#+id/outer"
android:tileMode="disabled" android:gravity="top">
<ImageView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/background"
android:scaleType="centerCrop"/>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/scrollView" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/container"></RelativeLayout>
</ScrollView>
</RelativeLayout>
From the above fig given, you can use GridView to draw UI as given. You can specify spacing between items also how many columns each row consists.
For reference check developer doc.
Check here for GridView example and doc
For the diagram shown you can go for a Grid Layout, you can customize grid layout for spacing between cells.
If it still doesn't fit your need then, my suggestion would be Linear layout with layout weights,however nested weights are a performance overhead.
http://developer.android.com/reference/android/widget/GridLayout.html
http://androidexample.com/Custom_Grid_Layout_-_Android_Example/index.php?view=article_discription&aid=76&aaid=100
Why are nested weights bad for performance? Alternatives?
Hope this help!!
I am trying to add a Layout to a LinaerLayout. while creating my view for the first time the layout is add nicely which means that the inflate and the addView are working well. but when I click a button to do the process a second time and add the same view another time it works but the view is add on top of the first one.
The Fragment :
// onCreateView, I bind the container with his LinearLayout
mLnPricing = (ViewGroup) mRootView.findViewById(R.id.lnPricing);
//some stuff
private void createPriceBlock() {
mParent = LayoutInflater.from(getActivity()).inflate(
R.layout.block_pricing, null);
//binding some views
mIbAddPricing.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
createPriceBlock();
}
});
mLnPricing.addView(mParent,0);
}
block_pricing.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="wrap_content"
android:orientation="vertical" >
//some text fields
</LinearLayout>
main_lauyout.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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" >
//some controllers
<LinearLayout
android:id="#+id/lnPricing"
style="#style/addLabels.AppTheme"
android:layout_height="wrap_content"
android:layout_marginTop="20dp" />
</ScrollView>
I don't know what's wrong with my code but for some weird reason the same code is working on another project.
What I expect: Add the new view at the position 0 and move the other views down.
what I have: The view is add on top of the previews one and a blank space is created below the view
The default orientation for a LinearLayout is horizontal. You've not specified an orientation for the LinearLayout that the new Views are being added to, so the old ones are being pushed off-screen to the right. Add android:orientation="vertical" to the lnPricing LinearLayout tag.
I am loading some newsitems from a webservice I want to add these to a HorizontalScrollView.
On iOS I would achieve by looping my news items and then add text labels as subviews to a ScrollView. I'am trying to do something similar in android but I can't seem to get it to work properly. No matter what I do, the items are listed below each other.
Heres my code to add the views:
public void setupViews(ArrayList<News> news)
{
HorizontalScrollView scrollView = (HorizontalScrollView) getView().findViewById(R.id.horizontalScrollView);
LinearLayout layout = (LinearLayout) getView().findViewById(R.id.linearLayout);
for(int i = 0; i < news.size(); i ++)
{
News newsItem = news.get(i);
TextView head = new TextView(this.getActivity());
head.setText(newsItem.getHead());
head.setId(100+i);
layout.addView(head);
}
}
The XML looks like this:
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="150dp"
android:id="#+id/horizontalScrollView" android:layout_gravity="center"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="#+id/linearLayout">
</LinearLayout>
</HorizontalScrollView>
It might be worth noting that I am doing this inside an fragment..
you can only add a single child layout to a ScrollView
in your case :
add a horizontal LinearLayout (set orientation as horizontal via adding this to your LinearLayout android:orientation="horizontal")
add stuff inside the horizontal LinearLayout
and things will fall right into place, horizontally :-)
currently i have the following layout
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_marginTop="9px"
android:layout_below="#+id/desc"
android:id="#+id/ll_item"
android:orientation="vertical"
android:paddingRight="3px"
android:paddingLeft="3px"
android:paddingBottom="5px"
android:paddingTop="5px"
android:background="#drawable/rounded_corner_lists" >
<!--
<ListView android:drawSelectorOnTop="false" android:id="#+id/lv" android:layout_height="fill_parent" android:layout_width="wrap_content" android:divider="#ddd" android:dividerHeight="1px" android:background="#drawable/white" />
-->
</LinearLayout>
the listview that i have commented out, i have tried to make this in the xml, with the height set to wrap_content, fill_parent, currently i am doing this programatically with the following code
LinearLayout ll_item = (LinearLayout) this.findViewById(R.id.ll_item);
if(list.length() > 0)
{
ll_item.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,calcListHeight(list));
listview = new ListView(this);
listview.setBackgroundResource(R.drawable.white);
listview.setDivider( new ColorDrawable(this.getResources().getColor(R.drawable.dividercolor)) );
listview.setDividerHeight(1);
listview.setCacheColorHint(0);
mAdapter = new JSONAdapter( list, this );
listview.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
ll_item.addView(listview, lp);
}
this is the result
so you can see in this image, that since i'm containing the listview in a linearlayout to get the rounded corner look, it doesn't just automatically stretch to contain the entire listview, is there any way to have the two elements just wrap the content vertically so there is no scrolling without me programatically setting the height ? ? ?
i guess one other thing i should mention is that i have all this layout in a scrollview, because i want this listview to be a tiny subsection of the entire layout, so it would be something like
-scrollview
-textview
-textview
-linearlayout
-listview
- button
here is a simpler layout of what i have
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent"
android:background="#drawable/bg" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/titlebar">
<ScrollView android:id="#+id/sv" android:layout_width="fill_parent" android:background="#drawable/bg"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout android:id="#+id/widget28"
android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="4dip"
>
<LinearLayout android:orientation="vertical" style="#style/rounded_corner_full_width_button"
android:id="#+id/editfields">
<ListView android:drawSelectorOnTop="false" android:id="#+id/lv" android:layout_height="fill_parent"
android:layout_width="wrap_content" android:divider="#ddd" android:dividerHeight="1px"
android:background="#drawable/white"/>
</LinearLayout>
</RelativeLayout>
</ScrollView>
</LinearLayout>
ListViews do not go in ScrollViews.
ListView is for displaying a limited window into unbounded content efficiently. If you were to "disable scrolling" on a ListView to put it within a ScrollView you lose all practical reason for using a ListView in the first place.
If you want to use a ListView to show lots of content or unbounded content but also have content above and below that scrolls with it, add header or footer views to the ListView using addHeaderView or addFooterView. If the list content is going to be a small portion of your overall layout as you describe, this probably isn't the best approach for you.
If you have a small, bounded set of content to present, go ahead and use a ScrollView and programmatically generate child views for your "list items" where appropriate.
A common pattern used in the framework to mix inflated XML content with programmatically generated content is to add a placeholder view in the layout XML, usually a LinearLayout or FrameLayout. Use findViewById to locate it at runtime and add generated child views to it.
You could even still use a ListAdapter with this approach if you have one written already, just call content.addView(adapter.getView(position, null, content)) in a loop for all adapter positions (where content is the placeholder view you located with findViewById). Note that this is only practical if you know that you have a small number of list items in the adapter!
Add a empty item on list end
Example:
ArrayList<String> options = new ArrayList<String>();
String lastItem = "";
int lastPosition;
options.add(lastItem);
public function addItem() {
lastPosition = options.size() - 1;
lastItem = options.get(lastPosition);
options.remove(lastPosition);
//add new items dynamically
for (int i = 0; i < 5; i++)
options.add("new item: "+i);
//add empty item
options.add(lastItem);
}