Please let me know that how i can add the views like images or button inside a relative layout. But on random position , Max number of images can be 10.
Please help me out. I am attaching a view how i want the final output.
Regards
Amit Sharma
In this case you should consider an AbsoluteLayout, it would make more sense. Since this way you can randomly generate and x and an y position for each child.
There are a ton of examples on the net, here is the first one found by a Google search. The gist is something like this:
To plot something like this on the screen:
You can have an AbsoluteLayout declared like this in your activity xml file:
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Declare your shapes -->
</AbsoluteLayout>
And then in your Activity or Fragment you will add your Shape objects at random positions, with something like:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
// Establish the working area
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int widthArea = displayMetrics.widthPixels;
int heightArea = displayMetrics.heightPixels;
//Init the random generator
Random r = new Random();
// Then for each Shape
// ...
AbsoluteLayout.LayoutParams pos =
(AbsoluteLayout.LayoutParams)shape.getLayoutParams();
pos.x = r.nextInt(widthArea);
pos.y = r.nextInt(heightArea);
shape.setLayoutParams(pos);
// ...
}
}
Related
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 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.
My problem is that i want change width of my TEXTVIEW (INPUT TEXT).
In emulator that code work success but when i try to work with my app in mobile that crash it.
My answer is: Why my app crash when i try to change .setWidth? and how can i solve my problem?
A lot of thanks.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.binomial);
EditText TextVA, TextVB, TextVC, EtiquetaA, EtiquetaB, EtiquetaC;
TextVA = (EditText)findViewById(R.id.editTextP);
TextVB = (EditText)findViewById(R.id.editTextK);
TextVC = (EditText)findViewById(R.id.editText3);
ArrayList<TextView> listaTexto = new ArrayList<TextView>();
listaTexto.add(TextVA);
listaTexto.add(TextVB);
listaTexto.add(TextVC);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int y = size.y;
int x = size.x;
ResolucionPantalla respant = new ResolucionPantalla(y, x);
for (int i=0;i<listaTexto.size();i++)
//ResolInput METHOD return size in px according to the screen size
listaTexto.get(i).setWidth(respant.ResolInput());
Button BotonCalcular = (Button)findViewById(R.id.buttonCalcular);
BotonCalcular.setOnClickListener(this);
}
EDIT: TextView to EditText
I see several potential issues...
For starters:
TextVA = (TextView)findViewById(R.id.editTextP);
Is R.id.editTextP an EditText? You are casting it as a TextView
And also:
Calling setWidth here will have no effect. There is an onLayout method for each view that gets called after onCreate is finished. The width/height get set to whatever is specified in your XML layout during that call
You can either extend and create your own EditText and override the onLayout method, or you can figure out how to size your views correctly via XML.
I need to create 4 buttons with equal width in a row. I know how to do that using linear layout and weights, but that's not quite acceptable for me. I have some other views that are related to my 4 buttons, so I'd like to do everything inside relative layout. Is it possible?
How about setting the buttons' width to a standard size?
<Button
android:width="75dp"
... />
Addition
To find the width of the display at runtime:
int width = getWindowManager().getDefaultDisplay().getWidth() / 4;
// Set this width to your buttons
I don't know for sure, but I think that the only way you can do this, without weight tags, is to runtime/programatically setup it. I've done this by setting a constant in a integer.xml, like the following:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="numberOfButtons">4</integer>
</resources>
And, in your Adapter/Activity class, something like the following:
DisplayMetrics dm = new DisplayMetrics();
// dm holds your structure of resolution
context.getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.getWidth();
btn1.setWidth(width/getInteger(R.integer.numberOfButtons));
btn2.seTwidth(width/getInteger(R.integer.numberOfButtons));
btn3.seTwidth(width/getInteger(R.integer.numberOfButtons));
btn4.seTwidth(width/getInteger(R.integer.numberOfButtons));
Hope this helps you in some way.
choose one of the views that will tell the others to have the same width and height . in order to fetch the size of a view , use something like this:
private static void runJustBeforeBeingDrawn(final View view, final Runnable runnable)
{
final ViewTreeObserver vto = view.getViewTreeObserver();
final OnPreDrawListener preDrawListener = new OnPreDrawListener()
{
#Override
public boolean onPreDraw()
{
Log.d(App.APPLICATION_TAG, CLASS_TAG + "onpredraw");
runnable.run();
final ViewTreeObserver vto = view.getViewTreeObserver();
vto.removeOnPreDrawListener(this);
return true;
}
};
vto.addOnPreDrawListener(preDrawListener);
}
Alternative to runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126
I want to add a view inside a FrameLayout programmatically and to place it in a specific point within the layout with a specific width and height. Does FrameLayout support this? If not, should I use an intermediate ViewGroup to achieve this?
int x; // Can be negative?
int y; // Can be negative?
int width;
int height;
View v = new View(context);
// v.setLayoutParams(?); // What do I put here?
frameLayout.addView(v);
My initial idea was to add an AbsoluteLayout to the FrameLayout and place the view inside the AbsoluteLayout. Unfortunately I just found out that AbsoluteLayout is deprecated.
Any pointers will be much appreciated. Thanks.
The following example (working code) shows how to place a view (EditText) inside of a FrameLayout. Also it shows how to set the position of the EditText using the setPadding setter of the FrameLayout (everytime the user clicks on the FrameLayout, the position of the EditText is set to the position of the click):
public class TextToolTestActivity extends Activity{
FrameLayout frmLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
frmLayout = (FrameLayout)findViewById(R.id.frameLayout1);
frmLayout.setFocusable(true);
EditText et = new EditText(this);
frmLayout.addView(et,100,100);
frmLayout.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("TESTING","touch x,y == " + event.getX() + "," + event.getY() );
frmLayout.setPadding(Math.round(event.getX()),Math.round(event.getY()) , 0, 0);
return true;
}
});
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/frameLayout1"
android:layout_height="fill_parent" android:layout_width="fill_parent">
</FrameLayout>
</LinearLayout>
You can also add a margin around the newly added view to position it inside the FrameLayout.
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.main); // or some other R.id.xxx
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(0, metrics.heightPixels - 20, 0, 0);
View v = new View(context);
v.setLayoutParams(params);
frameLayout.addView(v);
This will position the FrameLayout 20 pixels from the bottom of the screen.
Edit: completed the example so it stands by itself. And oh, yes it does work.
It's true that with FrameLayout all children are pegged to the top left of the screen, but you still have some control with setting their padding. If you set different padding values to different children, they will show up at different places in the FrameLayout.
From the link Quinn1000 provided:
You can add multiple children to a FrameLayout, but all children are pegged to the top left of the screen.
This means you can't put your View at a specific point inside the FrameLayout (except you want it to be at the top left corner :-)).
If you need the absolute positioning of the View, try the AbsoluteLayout:
A layout that lets you specify exact locations (x/y coordinates) of its children. Absolute layouts are less flexible and harder to maintain than other types of layouts without absolute positioning.
As for setting the width and height of the View, also like Quinn1000 said, you supply the v.setLayoutParams() method a LayoutParams object, depending on the container you chose (AbsoluteLayout, LinearLayout, etc.)
The thread here on stackOverflow at
How do you setLayoutParams() for an ImageView?
covers it somewhat.
For instance:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(30, 30);
yourImageView.setLayoutParams(layoutParams);
implies that you need to be defining a LinearLayout.LayoutParams (or in your case a FrameLayout.layoutParams) object to pass to the setLayoutParams method of your v object.
At
http://developer.android.com/reference/android/widget/FrameLayout.html
it almost makes it looks like you could ask your v to:
generateDefaultLayoutParams () via this method if you have not defined the parameters specifically.
But it's late, and those links are making my eyes bleed a little. Let me know if they nhelp any :-)