I have XML:
<RelativeLayout
android:id="#+id/IcdSearchMainPanel"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="UselessParent" >
<own_components.SearchOutput
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:orientation="vertical" >
<!-- HERE ARE ADDED ROWS WITH RESULTS IN JAVA CODE (look into SearchOutput.java) -->
</own_components.SearchOutput>
</ScrollView>
</RelativeLayout>
I have class SearchOutput.java (which extends LinearLayout) with such a method (generally it adds some graphical components to row and then this row to a ScrollView):
public void setResultOutput(ResultContainer result)
{
for (int i = 0; i < result.size(); i++)
{
LinearLayout resultRow = new LinearLayout(getContext());
resultRow.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
resultRow.setOrientation(LinearLayout.HORIZONTAL);
resultRow.setGravity(Gravity.CENTER_VERTICAL);
if (i % result.getIterationStep() == 0)
{
resultRow.setPadding(0, 0, 0, 10);
}
addView(resultRow);
ImageView langFlag = new ImageView(resultRow.getContext());
langFlag.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
try
{
Bitmap bitmap = BitmapFactory.decodeStream(MainClass.getAssetManager().open(Pathes.FLAGS_DIR + result.get(i)[0] + ".gif"));
langFlag.setImageBitmap(bitmap);
langFlag.setPadding(10, 0, 0, 0);
}
catch (IOException e)
{
Log.e("IMAGE_OPEN_EXC", e.toString());
}
resultRow.addView(langFlag);
TextView number = new TextView(resultRow.getContext());
number.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
number.setPadding(10, 0, 0, 0);
number.setText(result.get(i)[1]);
resultRow.addView(number);
TextView text = new TextView(resultRow.getContext());
text.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
text.setPadding(20, 0, 0, 0);
text.setText(result.get(i)[2]);
resultRow.addView(text);
}
}
PROBLEM:
No matter how many elements are in result variable there is always one row showned:
QUESTION:
What i do wrong? In my opinion logically everything is all right.
Another question: is this way efficient? Maybe i should add results in different way? I ask because there can be plenty of them.
A ScrollView can have only one child, so wrap your layouts in another big layout which you add to your ScrollView.
But as suggested in the comments, use a ListView!!! That's what it's for...especially when you have many rows to display. ListView will recycle unused views and definitely yield a better performance than your approach.
Scroll view is a container that make its own child scrollable, so, you will have to add a child to the scrollview, later add the items to that child.
No master what is the child, it can be list view, can be linear layout, etc.
Related
I want to set Imageview and Textview on same line in LinearLayout but the Imageview is always higher than the Textview.
Here is my code:
String b[] = cacBuocThucHien.split("#");
for (int j = 0; j < b.length; j++) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(30,30);
lp.setMargins(50, 0, 0, 0);
ImageView img = new ImageView(RecipesDetailActivity.this);
TextView tv = new TextView(RecipesDetailActivity.this);
img.setLayoutParams(lp2);
img.setImageResource(R.mipmap.testic);
tv.setLayoutParams(lp);
tv.setText(b[j] + "\n");
layoutHuongDan.addView(img);
layoutHuongDan.addView(tv);
}
This You can use to put image in one line.. and it will work in all kind of layouts. Hope this will help you
<LinerLayout>
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
....... // Put how many TextViews you want
<TextView
android:id="#+id/textn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinerLayout>
You can set visibility gone initially if you wanna show these textviews only after setting text.
Now in your activity make an array of ids of textviews like this...
public static int[] textRows = {R.id.text1, R.id.text2, ........ R.id.textn};
then use for loop for initializing them and setting text and images like this
TextView[] allTexts = new TextView[n];
for (int i = 0; i < n; i++) {
allTexts[i] = (TextView) findViewById(textRows[i]);
allTexts[i].setText("your text");
allTexts[i].setCompoundDrawables(left_image, null, null, null);
}
It will work. Try it out
set textview drawable left no need of extra imageview
android:drawableLeft="#drawable/img"
If you only want to show an icon beside that TextView, in my opinion you should consider using drawable icon feature of TextView
tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon, 0, 0, 0);
But if you would insist to using two views beside each other, using layout gravity would be useful in such circumstances.
lp.gravity= Gravity.CENTER_VERTICAL;
If you want to display only TextView and ImageView.. go for setting CompounDrawable in TextView itself..
But, for having two views side-by-side in LinearLayout programmatically try setting the orientation=horizontal, check out this link.
I'm trying to learn how to write Android programs, and I'm having trouble figuring out how padding works, in particular in a FrameLayout within a TableLayout.
private void fillTable(int nrows, int ncols) {
final int CENTER = 0x11; // used for "gravity" parameters
TableLayout table = (TableLayout) this.findViewById(R.id.tablelayout);
int counter = 1;
TextView text;
for (int i = 0; i < nrows; i++) {
TableRow row = new TableRow(this);
table.addView(row);
for (int j = 0; j < ncols; j++) {
View cell;
text = new TextView(this);
text.setTextColor(Color.BLUE);
text.setText(Integer.toString(counter++));
text.setGravity(CENTER);
if (i == 2 && j == 2) {
FrameLayout frame = new FrameLayout(this);
text.setLayoutParams(new FrameLayout.LayoutParams(90, 45, CENTER));
frame.setPadding(0, 0, 0, 0);
frame.addView(text);
cell = frame;
} else {
cell = text;
}
cell.setBackgroundColor((i + j) % 2 == 0 ? Color.YELLOW : Color.WHITE);
row.addView(cell);
cell.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1F/ncols));
}
row.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1F/nrows));
}
}
tablelayout just looks like this:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tablelayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</TableLayout>
I'm calling this with nrows=12 and ncols=5. I'm running on an emulator whose width is 720 pixels. If I change if (i==2&&j==2) to if (false), so that only an array of TextView is displayed, the columns are even, as I expect. However, with the code as written, the middle column is wider than the others.
I've also tried this adding android:stretchColumns="*" to the tablelayout definition and removing the weight parameter from cell.setLayoutParams, and the results are the same.
Assuming I have a reason to want to specify pixels for text.setLayoutParams (because of what I plan to do later), how would I get the column widths to be the same? Since 90*5 is well under 720, I don't understand why, or where, the extra width is being added.
Whenever you are dealing with weights, you must let the option take care of the remaining space. In this case width. Just set the width of each element to 0:
cell.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.MATCH_PARENT, 1F/ncols));
I have a xml view that contains a ScrollView(with a child LinearLayout).
...
<ScrollView
android:id="#+id/scrollView_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_marginTop="33dp" >
<LinearLayout
android:id="#+id/image_holder"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</LinearLayout>
</ScrollView>
...
I am trying to dynamically add some images, I want 3 per row.
private void createDice(LinearLayout ll, Integer required) {
ArrayList<Integer> images = new ArrayList<Integer>();
images.add(R.drawable.one);
images.add(R.drawable.two);
images.add(R.drawable.three);
images.add(R.drawable.four);
images.add(R.drawable.five);
images.add(R.drawable.six);
ScreenHelper screen = new ScreenHelper(MainActivity.this);
Map<String, Float> s = screen.getScreenSize();
Integer maxPerRow = (int) (s.get("width") / 90); // images are 89px wide
Log.d(TAG, "max across::"+maxPerRow);
Integer rows = (required / maxPerRow);
Log.d(TAG, "rows::"+rows);
for (int i=0; i < rows; i++) {
Log.d(TAG, "i::"+i);
// create linear layout for row
LinearLayout llAlso = new LinearLayout(this);
llAlso.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
//llAlso.setOrientation(LinearLayout.HORIZONTAL);
for (int j=0; j < 3; j++) {
Log.d(TAG, "j::"+j);
// create/add image for the row
ImageView iv = new ImageView(this);
iv.setImageResource(images.get(i));
llAlso.addView(iv);
}
// add to main layout
ll.addView(llAlso, i);
Log.d(TAG, "adding to main view");
}
}
I am testing with the required parameter value of 6.
The problem is that the first row of images gets added, but either the second isn't because it is getting added adjacent to the first row (and therefore off the screen) and not under it.
How to achieve my desired output?
Set the orientation in your image_holder layout to vertical. By default, the orientation of a LinearLayout is horizontal. That means that all child views will be added in a horizontal row. Since your child layouts use fill_parent for their width, only one child can fit in the row. By switching it to vertical, your layouts are added in a vertical column instead of in a row. That allows more layouts to be visible.
Also you should consider to use a GridLayout instead. That is made for exactly this case.
I am creating some buttons and add them to a linear layout which is defined as
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/mylayout">
</LinearLayout>
The buttons are created with
for (int i = 0; i < 3; i++)
{
Button btn = new Button(activity);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(1, 1, 1, 1);
btn.setText("Button");
btn.setPadding(0, 0, 0, 0);
mylayout.addView(pv, lp);
}
These buttons always have a margin (about 3px) which I'd like to remove. Is there anything I am missing? If I use a custom view which I created there is no space between them.
Should I set
lp.setMargins(-3, -3, -3, -3);
which removes the margin? Is there a drawback with this?
I do not really think they have a margin but it is related to the background of the button. Probably the default background of the button has a image like this one:
http://developer.android.com/guide/developing/tools/draw9patch.html
which includes fiction margins. Here you can find more info about 9-Patch.
http://developer.android.com/guide/topics/resources/drawable-resource.html
In my opinion if you want to remove the "margins", you should create a different background for the image because the -3 value is not a good workaround (IHMO).
Why are you using Layout Params .. simply add the view after its creation...
This will surely remove the problem
for (int i = 0; i < 3; i++)
{
Button btn = new Button(activity);
btn.setText("Button");
mylayout.addView(pv);
}
I'm trying to create a chess game board with 8x8 buttons. I'm using nested LinearLayouts. The problem is that there's a padding between each row of ImageViews that I can't get rid of. This is what I have sofar, the board should be square, but isn't:
public class BoardLayout extends LinearLayout {
public BoardLayout(Context context) {
super(context);
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
setLayoutParams(parms);
setOrientation(LinearLayout.VERTICAL);
setPadding(0, 0, 0, 0);
for (int i = 0; i < 8; i++) {
LinearLayout row = new LinearLayout(context);
row.setLayoutParams(parms);
row.setOrientation(LinearLayout.HORIZONTAL);
row.setPadding(0, 0, 0, 0);
for (int j = 0; j < 8; j++) {
ImageView button = new ImageView(context);
button.setLayoutParams(parms);
button.setImageResource(R.drawable.icon);
button.setAdjustViewBounds(true);
button.setPadding(0, 0, 0, 0);
row.addView(button);
}
addView(row);
}
setSquare();
}
public void setSquare() {
int size = Math.min(getWidth(), getHeight());
// setHeight(size); // Not Function, but this is what I need
// setWidth(size); // Not Function, but this is what I need
// also doesn't work
setLayoutParams(new LinearLayout.LayoutParams(size, size, 1.0f));
}
}
Solution:
As suggested TableLayout is better for what I'm trying to do. So the main class should be changed to a TableLayout and the nested LinearLayouts to TableRows.
But that alone didn't fix it, I also had to call the following in TableLayout:
setShrinkAllColumns(true);
setStretchAllColumns(true);
and for each item inserted, I had to also call:
setAdjustViewBounds(true);
TableLayout
Class Overview
A layout that arranges its children
into rows and columns. A TableLayout
consists of a number of TableRow
objects, each defining a row
(actually, you can have other
children, which will be explained
below). TableLayout containers do not
display border lines for their rows,
columns, or cells.
You are better off using a GridView or TableLayout instead of nested LinearLayouts, since that's what they're designed for.