Android horizontalscrollview. Adding views pragmatically - android

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 :-)

Related

Adding items to the ScrollView dynamically make it doesn't scroll

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.

ListView in a ScrollView Dilemma - How has this app managed to do it?

So basically you can't place a ListView in a ScrollView because the Scrolling ability clashes in both layouts. When I tried to do it, the ListView becomes completely useless and many other problems arise.
How has Facebook done it?
As you can see, the work section is a ListView and it's also a Scrollable layout so that the user can scroll down to view the Education section, which is also a ListView.
My code:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
android:layout_marginBottom="40dp">
<!-- More layouts -->
<ListView
android:id="#+id/work_list"
android:layout_below="#+id/recentpic"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</ScrollView >
I do not want a ListView Scroll bar
Therefore the scrolling dilemma is completely removed from the equation. Even when I disable the scroll bars, the problem persists.
Solution that I have in mind:
Generating the XML rows (Each Workplace of the ListView) and injecting it to the layout and avoiding the use of ListViews, similar to HTML Code Generation using Javascript.
What method do you think Facebook has used in their android app to get this done and what changes should I make to my code? :)
Have you tried using NestedScrollView? I think it's a NestedScrollView which contains a ListView and the whole thing is enclosed in a ScrollView. This link might help:
http://ivankocijan.xyz/android-nestedscrollview/
Okay so I managed to code my own idea I mentioned. It's a very 'sexy' code and it gets the job done :D
Here you go, guys. I hope it helps someone :)
So basically I'm inflating a Parent Layout with multiple Child Layouts dynamically and completely getting rid of ListViews in the view. Which makes is very simple to use it with a ScrollView and forget about that dilemma.
Parent Layout:
<RelativeLayout
android:id="#+id/work_list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</RelativeLayout>
Child Layout - work_single_item.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff">
<ImageView
android:id="#+id/work_pic"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:src="#mipmap/image_placeholder"/>
</RelativeLayout>
Coded the following lines in the OnCreate function of the Parent Layout.
RelativeLayout parent = (RelativeLayout) findViewById(R.id.work_list);
//array containing all children ids
ArrayList<Integer> children = new ArrayList<>();
//adding 10 children to the parent
for(int i=0;i<10;i++) {
RelativeLayout child = new RelativeLayout(this);
View tempchild = getLayoutInflater().inflate(R.layout.work_single_item, null);
child.addView(tempchild);
child.setId(i); //setting an id for the child
children.add(i); //adding the child's id to the list
if(i!=0) //if it isn't the 1st child, stack them below one another, since the 1st child does not have a child to stack below
{
RelativeLayout.LayoutParams params
= new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, children.get(i - 1)); //stack it below the previous child
child.setLayoutParams(params);
}
parent.addView(child); //add the new child
}

android which layout for elements side by side

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!!

GridLayout isn't fully visible while scrolling left

I'm trying to do "Minesweeper". Basically I have GridLayout inside ScrollView and HorizontalScrollView. Everything is OK if all fields are on screen (in my case ImageButtons). But if I zoom in (increase size of ImageButtons), HorizontalScrollView works just partly.
Take a look at this pics:
More I zoom in more fields are hidden on the left side and more free space is on right side.
XML layout:
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<HorizontalScrollView
android:id="#+id/horizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<GridLayout
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" >
</GridLayout>
</HorizontalScrollView>
</ScrollView>
And how I add buttons dynamically to GridLayout:
field = (GridLayout) findViewById(R.id.grid);
field.setColumnCount(N);
field.setRowCount(N);
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
ImageButton b = new ImageButton(this);
b.setId(j*10+i);
b.setImageResource(R.drawable.unknowen);
b.setTag(R.drawable.unknowen);
b.setScaleType(ImageView.ScaleType.CENTER_CROP);
b.setPadding(5,5,5,5);
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.setMargins(-7,-7,-7,-7);
params.width = fieldSize;
params.height = fieldSize;
b.setOnClickListener(this);
b.setOnLongClickListener(this);
field.addView(b, params);
}
}
I apologize for bad language, and thanks for help!
First, I'm pretty sure nesting a GridView (which implements scroll listening) inside a HorizontalScrollView (which also implements scroll listening) isn't likely to work as expected.
But, if you're doing horizontal scrolling only, you may want to just add android:scrollbars="horizontal" to the GridView and get rid of the HorizontalScrollView entirely (but I'm not sure if you also require vertical scrolling, which would cause this answer to give more problems).
As for adding data to the GridView, you should be changing the data in the LIST of objects the GridView's Adapter is backed by; not the actual View itself. The Views inside the GridView are generated as-needed by the Adapter and are populated in the Adapter's override-able getView() method by mapping the position in the View with the position in your dataset.
Also note, after changing the dataset, you MUST ALWAYS call notifyDataSetChanged() on the Adapter in order for it to refresh its View's with the updated result.

how can i automatically size listview so it doesn't scroll

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);
}

Categories

Resources