Can anyone tell me why this is happening, please?
What I'm trying to do is get them to all align centered, regardless of how many there are. It works lovely for quite a few, and even works with only 1 more, but 4 seems to do this. I'm adding them in code, here:
LinearLayout guessHolders = (LinearLayout)findViewById(R.id.guessHolders);
guessHolders.removeAllViews();
currentLetterPosition = 0;
final Bitmap emptyLetterHolder = BitmapFactory.decodeResource(getResources(), R.drawable.letter_holder);
for(int i=0; i<Globals.mUser.getLevel().getSolution().length(); i++)
{
final EmptyLetter tmp = new EmptyLetter(this, i);
tmp.setImageBitmap(emptyLetterHolder);
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(Globals.defaultLetterSizes[mBlockSize],
Globals.defaultLetterSizes[mBlockSize], 1);
parms.weight = 1;
parms.gravity = Gravity.CENTER_HORIZONTAL;
tmp.setLayoutParams(parms);
tmp.setAdjustViewBounds(false);
tmp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("PP2", tmp.getId() + " << the clicked empty letter holder id");
currentLetterPosition = tmp.getId();
tmp.setImageBitmap(emptyLetterHolder);
setChosenLetter(tmp.getId(), '\u0000');
}
});
currentEmpties.add(tmp);
guessHolders.addView(tmp);
}
I've tried setting gravity, weightsum, width and height of the box views as well as the parent container LinearLayout, but nothing seems to shift them.
Any help is greatly appreciated!
Fixed it. With the following:
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(Globals.defaultLetterSizes[mBlockSize],
Globals.defaultLetterSizes[mBlockSize], 0);
parms.gravity = Gravity.CENTER_HORIZONTAL;
tmp.setLayoutParams(parms);
So, I set the weighting to zero and leave the rest to the OS. Works for all of them now. Marvelous.
Cheers
Related
I am creating a Table of buttons, to control a LED Matrix via Bluetooth.
I have found on the web Brian's Video Tutorials and followed his Dynamic Buttons and Images video to implement this.
Here is the code:
public class DrawerMode extends Activity {
private static final int NUMOFCOL = 15;
private static final int NUMOFROW = 8;
Button buttons[][] = new Button[NUMOFROW][NUMOFCOL];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Assign content
setContentView(R.layout.activity_draw_mod);
fillTable();
}
private void fillTable() {
TableLayout tableLayout = (TableLayout) findViewById(R.id.drawer_table);
for( int iter_R = 0; iter_R!= NUMOFROW; iter_R++){
TableRow tableRow = new TableRow(this);
tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,TableLayout.LayoutParams.WRAP_CONTENT,1.0f));
tableLayout.addView(tableRow);
for(int iter_C = 0; iter_C != NUMOFCOL; iter_C++){
final int FINAL_COL = iter_C;
final int FINAL_ROW = iter_R;
Button button = new Button(this);
button.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT, 1.0f));
button.setText("" + iter_C + "," + iter_R);
button.setPadding(0, 0, 0, 0);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
whenBtnClicked(FINAL_COL, FINAL_ROW);
}
});
tableRow.addView(button);
buttons[iter_R][iter_C] = button;
}
}
}
private void whenBtnClicked(int col, int row) {
//Toast.makeText(this, "Button clicked: " + FINAL_COL + "," + FINAL_ROW, Toast.LENGTH_SHORT).show();
Button button = buttons[row][col];
// Lock Button Sizes:
lockButtonSizes();
int newWidth = button.getWidth();
int newHeight = button.getHeight();
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_dark_blue);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true);
Resources resource = getResources();
button.setBackground(new BitmapDrawable(resource, scaledBitmap)); // Change text on button:
button.setText(" ");
}
private void lockButtonSizes(){
for (int row = 0; row < NUMOFROW; row++){
for (int col = 0; col < NUMOFCOL; col++){
Button button = buttons[row][col];
int width = button.getWidth();
button.setMinWidth(width);
button.setMaxWidth(width);
int height = button.getHeight();
button.setMinHeight(height);
button.setMaxHeight(height);
}
}
}
}
It works great, but while testing I have found the following issue.
When I click random buttons it works great:
[img]http://i.imgur.com/OYFJ6zJ.png?1[/img]
But when I complete a row (all elements on row are clicked), and I mean any row it starts to rescale the buttons in the whole table:
[img]http://i.imgur.com/ttAz4U0.png?1[/img]
I was thinking that maybe the LayoutParams of the TableRow should be changed, but not sure about that. What am I missing here?
I think you're right about the layout parameters needing to change. This line
tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,TableLayout.LayoutParams.WRAP_CONTENT,1.0f));
would cause the row's height to shrink in size if no button had displayed text, which seems to be what's happening. The TableLayout.LayoutParams does support setting fixed width/height, which you could sensibly calculate by first getting the device's screen width/height and dividing accordingly.
Or, if that gets to cumbersome, you could set -- though this may be too much of a hack -- the default text in the TextViews in the "unset" buttons with some transparent text (e.g., "1,1") so that the height is the same as a set button. This SO answer answer shows how to make transparent text.
I am certain that this is not a good solution for all cases. But just as I thought, the problem was with
button.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT, 1.0f));
If I understand correctly after the entire row was clicked, since the LayoutParams change according to the MATCH_PARENT value, the TableRow rescales the whole row to meet this criteria,since the height of the entire row is the same now. Not sure if it happens exactly this way, but I think this is the case because of my solution.
My work around is to add specific values for the LayoutParams, instead of leaving it the system to figure it out:
button.setLayoutParams(new TableRow.LayoutParams( 75, 50, 1.0f));
I am aware this is not how it should be done. But since I have a deadline to met soon, I can't spend any more time with it. Most likely the correct way to do this is Jason's suggestion to get the screen size and calculate it. You can do this with:
Display display = getWindowManager().getDefaultDisplay(); Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
The problem is to come up with a correct formula to calculate this values you can pass to the LayoutParam. If anyone can figure this out please do post your solution and I will accept that answer. At this point I accept Jason's suggestion.
I tried to use below code, but the textviews do not change line after it reach the end of screen.
RelativeLayout ll = (RelativeLayout)findViewById(R.id.viewObj);
int lastid=0;
for (int i=0; i<100; i++) {
String teststr = " hello ";
TextView textView2 = new TextView(this);
textView2.setId(i+1);
textView2.setTextSize(30);
textView2.setBackgroundColor(Color.GREEN);
textView2.setTextColor(Color.RED);
textView2.setTypeface(Typeface.MONOSPACE);
textView2.setText(teststr+String.valueOf(i));
if (i>0)
{
RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lay.addRule(RelativeLayout.RIGHT_OF, lastid);
ll.addView(textView2, lay);
} else {
ll.addView(textView2);
};
lastid = textView2.getId();
}
However, I dont know how to determine when to change line. I just keep on putting new textview to the right of the last one created. Can anyone tell me the correct logic to do the task? many thanks.
Easy fix. Switch to a dynamically-created LinearLayout, and set its orientation to vertical:
lay.setOrientation(LinearLayout.VERTICAL);
I'm adding some views to a LinearLayout with a slight overlap in the top, here is the code:
viewHolder.linearLayout.removeAllViews();
for (int i = 0; i < conversation.getPreviousMessages().length; i++) {
View messageView = layoutInflater.inflate(R.layout.layout_previous_message_row, null);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, -5, 0, 0);
viewHolder.linearLayout.addView(messageView, layoutParams);
}
In this code some views are added to layout in order A, B, C, with A to the back and C to the front.
I would like to reverse the order, making A to the front and C to the back.
I have tried this, but nothing happens.
How can I reach this?
Please, could you people bring me some code?
Thanks in advance.
There is the capability to change the z-order of a view if that is the question that you are asking. And if so desired, you can usually get the effect of using the View.bringToFront() capabilities within that class.
View.bringToFront
After some punches against the wall, I finally found a solution:
1.- I changed the layout from being a LinearLayout to being a RelativeLayout because bringChildToFront has a weird behavior among LinearLayout.
2.- After adding the view to the RelativeLayout, I iterated backwards over the views and I made a bringChildToFront.
Here is the code:
for (int i = 0; i < conversation.getPreviousMessages().length; i++) {
View messageView = layoutInflater.inflate(R.layout.layout_previous_message_row, null);
messageView.setId(99+i);
viewHolder.relativeLayout.addView(messageView);
if (i > 0) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, -5, 0, 0);
layoutParams.addRule(RelativeLayout.BELOW, 99+i-1);
messageView.setLayoutParams(layoutParams);
}
}
for (int i = viewHolder.relativeLayout.getChildCount() - 1; i >= 0; i--) {
viewHolder.relativeLayout.bringChildToFront(viewHolder.relativeLayout.getChildAt(i));
}
I hope it help someone.
I have created two imageViews promatically as shown below:
public void createImageViews(Integer count){
ImageView[] imageViewArray = new ImageView[count];
for (int i = 0; i < count; i++ ) {
imageViewArray[i] = new ImageView(getBaseContext());
imageViewArray[i].setId(i); // unique property for every imageView
if(i==0){
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
imageViewArray[i].setLayoutParams(params);
imageViewArray[i].setBackgroundResource(imagesForIv[i]);
_UIRLParent.addView(imageViewArray[i]);
Log.v("first", "first"+i);
}
else if(i < 3){
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.RIGHT_OF,imageViewArray[i].getId());
imageViewArray[i].setBackgroundResource(imagesForIv[i]);
_UIRLParent.addView(imageViewArray[i],params);
Log.v("second", "second"+i);
}
}
I just need to place the second imageView toRightOf first imageView. Can someone help me. This is eating away a lot of my time.
try https://stackoverflow.com/a/5191159/1436931
you are using wrong index values.
at line
params.addRule(RelativeLayout.RIGHT_OF,imageViewArray[i].getId());
you aligning current image RIGHT of current image. :)
you need to track the index of last imageView id i.e left Image view
you need something like this
params.addRule(RelativeLayout.RIGHT_OF,imageViewArray[i-1].getId());
I'm creating a button dynamically. The number of button is depend on the size of arraylist. the problem is, after creating the button I will add to the layout using addview method. The problem is I'm using linear layout, as by default orientation for linear layout is horizontal, so the button will fill the layout horizontally. Because of that some of the button is not visible. What I'm trying to achieve is something look like this
My code is like below:
Button[] tv = new Button[arraylist.size()];
for(int i=0;i<arraylist.size();i++){
tv[i] = new Button(getApplicationContext());
tv[i].setText(arraylist.get(i).toString());
tv[i].setTextColor(Color.parseColor("#000000"));
tv[i].setTextSize(20);
tv[i].setPadding(15, 5, 15, 5);
linearlayout.addView(tv[i]);
}
If I set the orientation of linear layout to vertical the button will fill vertically. So if there any solution to create the button dynamically and fill the layout both horizontal and vertical as shown by image.
There is not a canned layout in the SDK that does exactly what you are aiming for (i.e. lay out as many children horizontally as will fit, then flow to the next line to lay out some more), so you will need to create a custom ViewGroup that accomplishes this purpose. Luckily for you, Romain Guy created one live on-screen during a presentation at Devoxx.
Here is a link to that presentation video.
Here is a link to the sample code and slides.
HTH
After 2 days struggling thinking bout this problem finally I've found the solution. I've try put all my contact list, store it in arraylist and create button for each element and I'm quite satisfy with the result after display on the screen. Here is how I do the trick. I really appreciate for any comment from others.
variable declaration;
int currWidth;
int currCounter;
boolean isNewLine;
LinkedList<HashMap<String,Object>> button;
ArrayList<String> nameNumber = new ArrayList<String>();
contactWrapper = (LinearLayout) findViewById(R.id.multiple_selection);
create button onClick event;
for(int i=0;i<nameNumber.size();i++){
tv[i] = new Button(getApplicationContext());
String[] namePhone = nameNumber.get(i).toString().split("##");
phoneNumber.add(namePhone[1]);
tv[i].setText(namePhone[0]);
tv[i].setTag(namePhone[1]);
tv[i].setTextColor(Color.parseColor("#000000"));
tv[i].setTextSize(20);
tv[i].setPadding(15, 5, 15, 5);
tv[i].measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
HashMap<String, Object> map = new HashMap<String,Object>();
map.put("button", tv[i]);
map.put("width", tv[i].getMeasuredWidth());
button.add(map);
}
drawLayout();
drawlayout method is where I add button and arrange accordingly to fit the layout;
public void drawLayout(){
int counter=0;
contactWrapper.setOrientation(LinearLayout.VERTICAL);
currCounter=0;
currWidth=0;
isNewLine=false;
LinearLayout[] row = new LinearLayout[nameNumber.size()];
row[currCounter] = new LinearLayout(getApplicationContext());
#SuppressWarnings("rawtypes")
Iterator it = button.iterator();
for(int i = 0; i<button.size(); i++){
it.next();
row[currCounter].setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
currWidth += Integer.parseInt(button.get(i).get("width").toString());
if(isNewLine){
if(currWidth < contactWrapper.getWidth()){
row[currCounter].addView((View) button.get(i).get("button"));
if(!it.hasNext()){
contactWrapper.addView(row[currCounter]);
}else{
if(contactWrapper.getWidth()<(currWidth+Integer.parseInt(button.get(i+1).get("width").toString()))){
isNewLine=true;
contactWrapper.addView(row[currCounter]);
currCounter+=1;
row[currCounter] = new LinearLayout(getApplicationContext());
currWidth=0;
}else{
isNewLine=false;
}
}
}else{
isNewLine=true;
contactWrapper.addView(row[currCounter]);
currCounter+=1;
row[currCounter] = new LinearLayout(getApplicationContext());
currWidth=0;
}
}else{
if(currWidth < contactWrapper.getWidth()){
if(!it.hasNext()){
row[currCounter].addView((View) button.get(i).get("button"));
contactWrapper.addView(row[currCounter]);
}else{
row[currCounter].addView((View) button.get(i).get("button"));
if(contactWrapper.getWidth()<(currWidth+Integer.parseInt(button.get(i+1).get("width").toString()))){
isNewLine=true;
contactWrapper.addView(row[currCounter]);
currCounter+=1;
row[currCounter] = new LinearLayout(getApplicationContext());
currWidth=0;
}else{
isNewLine=false;
}
}
}else{
isNewLine=true;
contactWrapper.addView(row[currCounter]);
currCounter+=1;
row[currCounter] = new LinearLayout(getApplicationContext());
currWidth=0;
}
}
counter++;
}
}
this code quite messy + I'm not fully utilize the size of array for
LinearLayout[] row = new LinearLayout[nameNumber.size()];
but it work for me.
use TableLayout instead of LinearLayout this is tutorial hope this will help you to get the idea
Does you set android:layout_width="fill_parent"?
Do this if you don't.
Well, you can try using more sophisticated way. You can create horizontal linear layout, and add buttons to it. Every time you're attempting to add new button, you check if there is place for it, by finding difference between layout's and buttons widths.
Each time your horizontal layout is filled, you add it to another vertical layout, and create another horizontal layout to store buttons left.
I used that trick in my apps.
try this its working fine
this.row = (LinearLayout)findViewById(R.id.tags);
this.row.setOrientation(LinearLayout.VERTICAL);
LinearLayout one = new LinearLayout(this);
//get the size of the screen
Display display = getWindowManager().getDefaultDisplay();
this.screenWidth = display.getWidth(); // deprecated
this.screenHeight = display.getHeight();// depreceted
for(int i=0; i<6; i++) {
one.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
this.button = new Button(this);
button.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
if(i==0) {
this.button.setText("Muhammad Aamir");
} else if(i==1) {
this.button.setText("Ahsan");
} else if(i==2) {
this.button.setText("Mujahid");
} else if(i==3) {
this.button.setText("Waqas");
} else if(i==4) {
this.button.setText("Ali");
} else {
this.button.setText("Ahmer");
}
//get the size of the button text
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(button.getTextSize());
mPaint.setTypeface(Typeface.create(Typeface.SERIF, Typeface.NORMAL));
float size = mPaint.measureText(button.getText().toString(), 0, button.getText().toString().length());
size = size+14;
this.totalTextWidth += size;
if(totalTextWidth < screenWidth) {
one.addView(button);
} else {
this.row.addView(one);
one = new LinearLayout(this);
one.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
one.addView(button);
this.totalTextWidth = size;
}
}
this.row.addView(one);
}