I would like to inflate imagebuttons programmatically to a linearlayoutm, coded as follows:
Code:
public void set_keyboard_words(int row, int start, int end)
{
for (int p = start; p <= end; p++)
{
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(btn_ball_sq,btn_ball_sq);
params.setMargins(0, 0, 0, 0);
keyboard_btn = new ImageButton(this);
keyboard_btn.setId(p);
final int id_ = keyboard_btn.getId();
keyboard_btn.setImageResource(BUTTON_IMG[p-1]);
keyboard_btn.setBackgroundResource(R.drawable.btn_blue_selector);
keyboard_btn.setScaleType(ImageView.ScaleType.FIT_XY);
keyRow1.addView(keyboard_btn, params);
keyboard_btn.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
button_action(id_);
}
});
}
}
Xml:
<LinearLayout
android:id="#+id/keyRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:splitMotionEvents="false" >
</LinearLayout>
Background:
The imagebuttons are some balls.
The imagebuttons could be inflated to the linearlayout keyRow1.
However, I do not know how to set the image resources to the imagebuttons correctly. The balls inflated are so small instead of fitting to XY of the buttons.
Screenshot as follows:
If image set as keyboard_btn.setImageResource(BUTTON_IMG[p-1]); (with blue backgrounds as BackgroundResource for seeing the actual size of button), the balls are very small
If image set as keyboard_btn.setBackgroundResource(BUTTON_IMG[p-1]);, the size is now proper but the actual backgroundResource cannot be set anymore
Question:
I would like to use the method of setImageResource for the imagebuttons as the button background would later be changed to other background image upon pressed.
How could I set the imagebutton's image using setImageResource but with size of balls similar to the 2nd screenshot??
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
keyboard_btn = new ImageButton(this);
keyboard_btn.setId(p);
final int id_ = keyboard_btn.getId();
keyboard_btn.setImageResource(BUTTON_IMG[p-1]);
keyboard_btn.setBackgroundResource(R.drawable.btn_blue_selector);
keyboard_btn.setLayoutParams(params);
Just try the above code, if the image doesn't shrink then you need to optimize the image based on the width you get for each button from screen width.
Related
In one of the activity of my app, I have a button where I want to display an image with each button click. For example:
By clicking the button of my activity, an image appears on screen as shown.
The second and following clicks on the button will results in the new image to append accordingly.
I would like to have some suggestion on how do I achieve this.
I made something similar to this but with TextView. Basically I did this:
XML:
For my case I made TableLayout Ex:
<TableLayout
android:id="#+id/existedTableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/margin_standard">
<TableRow>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/number_text"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large" />
</TableRow>
</TableLayout>
Activity
Note: Change it to ImageView for your case
/* //Get the TableLayout. Ex:
private TableLayout existedTableLayout = findViewById(R.id.existedTableLayout);
*/
/* Make onClickListerner to call below function */
private void addTableRowDynamically() {
//Make new Row
TableRow newRow= new TableRow(this);
TextView newNoTextView = new TextView(this);
//some TextView method, do your research about ImageView
newNoTextView.setLayoutParams(new TableRow.LayoutParams(0,ViewGroup.LayoutParams.WRAP_CONTENT, 1));
newNoTextView.setText("this is text");
newNoTextView.setTextAppearance(this, android.R.style.TextAppearance_DeviceDefault_Large);
// Add the TextView to the newRow
newRow.addView(newNoTextView);
// Add the newRow which contain the TextView to the TableLayout, below
existedTableLayout.addView(newRow, existedTableLayout.getChildCount());
}
Add a vertical LineaLayout and add views dynamically:
private void createViews() {
for (int i = 0; i < numberOfViews; i++) {
view = new ImageView(context);
int width = 300;
int height = 50;
view.setPadding(18, 10, 0, 0);
view.setLayoutParams(new LinearLayout.LayoutParams(width, height));
view.setId(i);
view.setGravity(Gravity.CENTER_VERTICAL);
view.setBackgroundColor(Color.parseColor("someColor"));
viewList.add(view);
}
}
Rect rectf = new Rect();
for (ImageView view : viewList) {
view.getGlobalVisibleRect(rectf);
coordinates.add(rectf.bottom);
}
I'm having an issue working with layouts, I've a linear layout (could be a relative layout or a table layout) which will contain an undefined number of buttons when the activity is loaded. This means, the quantity of buttons will be determined when the activity is being created. The thing is, I'm trying to fit them all in one line (with a center gravity) without changing each buttons' width UNTIL one of them reaches the margin of the screen. In other words, I want the buttons JUST to resize when at least one of them reaches the margin of the screen. That is because, I can't determine the space they're going to use because they are not created.
My actual linear layout:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:id="#+id/linearLayout_1"
android:layout_above="#+id/linearLayout_2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="30dp"
android:orientation="horizontal"
android:gravity="center"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
</LinearLayout>
Piece of code that creates the buttons:
protected void hacerVisiblesRespuesta(){
ViewGroup linearLayout = (ViewGroup) findViewById(R.id.linearLayout);
assert linearLayout != null;
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40, getResources().getDisplayMetrics());
for(int i = 0; i < longuitudPalabra; i++){
String boton = "btn_rsp" + Integer.toString(i+1);
Button bt = new Button(this);
bt.setText("");
bt.setId(getResourceId(boton,"id",getPackageName()));
bt.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT
, height
, 1.0f));
bt.setTextColor(Color.BLACK);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickBotonRespuesta(v);
}
});
bt.setVisibility(View.VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
bt.setBackground(getDrawable(R.drawable.bgbtnrsp));
}else{
//bt.setBackgroundDrawable(getDrawable(R.drawable.bgbtnrsp));
}
bt.setTextSize(20);
Typeface typeFace= Typeface.createFromAsset(getAssets(),"fonts/Montserrat-Regular.ttf");
bt.setTypeface(typeFace);
linearLayout.addView(bt);
}
}
I've tried many things, one of them was to make the buttons' width variable with weight property. The thing is if there are a small quantity of buttons, lets say 4, their width ended up enormous. Is there any way to achieve this through code? Thanks.
have you tried this?
button.setLayoutParams (new LayoutParams(50, LayoutParams.WRAP_CONTENT)
I'm trying to create Buttons in LinearLayout dynamically, and I want to add those in vertical and horizontal way.
At first, add a button A in the layout, and if there's enough space between button A and screen edge, add button B to the right of button A (horizontally). Otherwise, add button B below button A (vertically).
My current layout :
<LinearLayout
android:id="#+id/btn_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
in class :
LinearLayout btnLayout = (LinearLayout) findViewById(R.id.btn_layout);
btnLayout.removeAllViewsInLayout();
for(Tag tag : tagList.getChildTags()) {
Button button = new Button(this);
button.setId(tag.getId());
button.setText(tag.getName());
btnLayout.addView(button);
}
In this case, if I set orientation as horizontal, then some of buttons are not showing (cut-off by screen), and if I set as vertical, it looks pretty bad.
Is there any way to solve this problem? Thanks everyone in advance!
You can achieve this but not in a trivial way. I'll explain how I do something similar (in my case, I add TextViews) to TableRows, if they fit.
With this approach you'll have to use a TableLayout and add TableRows to it with your Buttons. So you might replace your "#+id/btn_layout" LinearLayout to be a TableLayout instead.
Firstly, to get the screen's width, use something like this:
final Display display = getWindowManager().getDefaultDisplay();
final Point size = new Point();
display.getSize(size);
final WindowManager.LayoutParams params = getWindow().getAttributes();
// Your screen's width will be stored within your params.width value
You'll use this to know if the current Button still fits the screen's width within the current TableRow or it has to be added to a new one. So now, use something like this to create your buttons:
int currentRowsWidth = 0;
TableLayout tl = (TableLayout) findViewById(R.id.my_table_layout);
TableRow currentRow = new TableRow();
for (Tag tag : tagList.getChildTags()) {
Button button = new Button(this);
button.setId(tag.getId());
button.setText(tag.getName());
// There's where you check whether it still fits the current `TableRow` or not
if (currentRowsWidth + button.getWidth() < params.width) {
currentRowsWidth += button.getWidth();
currentRow.addView(button);
}
else {
// It doesn't fit, add the currentRow to the table and start a new one
tl.add(currentRow);
currentRow = new TableRow();
currentRow.addView(button);
currentRowsWidth = button.getWidth();
}
}
It might happen that once you get out of the loop there are still Buttons to add in the currentView, simply test it:
if (currentRow.getChildCound() > 0)
tl.add(currentRow);
I'm writing this from head, so some things might not compile at first time, but I hope you get the idea.
I am getting list of phone companies from web service and i have to set it to textview but the problem is i am not getting alignment as above image.How to achieve it.
From what I understand, you want to add text views one beside the other, but when they overflow (go out of the screen) the next text view should be placed in the next line.
Doing this is not trivial. Implementing something like this (optimally and correctly) requires understanding of how android draws views (onMeasure and onLayout). However if you do not care about efficiency that much (mainly because you are going to do it only for a small portion of the view) then here is my quick hack:
mContainer = (RelativeLayout) findViewById(R.id.container);
// first layout all the text views in a relative layout without any params set.
// this will let the system draw them independent of one another and calculate the
// width of each text view for us.
for (int i = 0; i < 10; i++) {
TextView tv = new TextView(getApplicationContext());
tv.setText("Text View " + i);
tv.setId(i+1);
tv.setPadding(10, 10, 20, 10);
mContainer.addView(tv);
}
// post a runnable on the layout which will do the layout again, but this time
// using the width of the individual text views, it will place them in correct position.
mContainer.post(new Runnable() {
#Override
public void run() {
int totalWidth = mContainer.getWidth();
// loop through each text view, and set its layout params
for (int i = 0; i < 10; i++) {
View child = mContainer.getChildAt(i);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// this text view can fit in the same row so lets place it relative to the previous one.
if(child.getWidth() < totalWidth) {
if(i > 0) { // i == 0 is in correct position
params.addRule(RelativeLayout.RIGHT_OF, mContainer.getChildAt(i-1).getId());
params.addRule(RelativeLayout.ALIGN_BOTTOM, mContainer.getChildAt(i-1).getId());
}
}
else {
// place it in the next row.
totalWidth = mContainer.getWidth();
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.BELOW, mContainer.getChildAt(i-1).getId());
}
child.setLayoutParams(params);
totalWidth = totalWidth - child.getWidth();
}
mContainer.requestLayout();
}
});
Basically, I let the system do the layout and measurement for me in the first round(s) of drawing. Then using the widths of each text view now available, I reset the layout params based on the wrapping logic and do the layout again.
Try it with text of different size, it will auto adjust. I would say this solution is pretty hacky but it works. If you are not satisfied with it take a look at this.
use
android:textAlignment="textStart"
I have created a basic RelativeLayout in my XML file. In my code, I want to dynamically create several ImageViews and place them at different locations within the RelativeLayout. Everything I've tried (ImageView.setX(), ImageView.setTranslationX(), ImageView.setPadding()) either says I need a higher API level (11+) or causes the ImageView to not appear.
If I do not try to do anything with the location of the ImageView, then the image does appear on the screen in the (0,0) position.
This simple app will layout 15 icons in three rows dynamically using RelativeLayout. There is no reason to use AbsoluteLayout - it is also deprecated.
The main activity.
public class MainActivity extends Activity {
private int mWidth;
private int mTile;
private int mColMax = 5;
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
// the screen width is need to work out the tile size
mWidth = mContext.getResources().getDisplayMetrics().widthPixels;
// how wide (and high) each icon will be to fit the screen.
mTile = (mWidth / mColMax);
setContentView(R.layout.activity_main);
// layout the icons
initUI();
}
/**
* Layout 15 icon images in three rows dynamically.
*/
private void initUI() {
// this is the layout from the XML
ViewGroup layout = (ViewGroup) findViewById(R.id.main_layout);
ImageView iv;
RelativeLayout.LayoutParams params;
int i = 0;
int row = 0;
int col = 0;
do {
params = new RelativeLayout.LayoutParams(mTile,mTile);
params.setMargins((col * mTile), (row * mTile), 0, 0);
iv = new ImageView(mContext);
iv.setAdjustViewBounds(true);
iv.setScaleType(ScaleType.FIT_CENTER);
iv.setImageResource(R.drawable.ic_launcher);
iv.setLayoutParams(params);
layout.addView(iv);
if (col == mColMax) {
row++;
col = 0;
} else {
col++;
}
} while (++i <= 16);
}
}
And the layout XML.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
RelativeLayouts are used to place items in relationship to other items. YOu don't use them to place layouts at specific positions like a setX. If you want to place the new item relative to existing items, look at RelativeLayout.LayoutParams- you can set layout_alignXXX and layout_toXXXOf type parameters through them.
If you need an exact pixel position, use the deprecated AbsoluteLayout. Just be aware its going to look ugly as heck on any device with a different aspect ratio or size screen without a ton of work.