Align and space 3 images in android, taking full width - android

I have 3 images and I would like to achieve to have something like my
It is supposed to take the full width of the screen, a height of 100dp (or whatever I will choose).
The images I have are square and big. I want them to have a height of 100dp, keep their aspect ratio (square) and be spaced equally
What I get with this code is 3 images that take 1/3 of the width, not squared with no space in between
I have tried various things (playing with scaleType, ...) but I am stuck (apart from setting the width to 100dp manually for each of them, which I conceptually don't like)
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="#+id/img1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/img1"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="#+id/img2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/img2"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="#+id/img3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/img3"/>
</LinearLayout>
</LinearLayout>

I'd do it with code:
int resx = getWindowManager().getDefaultDisplay().getWidth();
int spaceBetweenPics = (resx - 300) / 2; // Two spaces taking resolution - 3 images size
Bitmap [] pics = New Bitmap[3];
for (int i = 0; i < 3; i++) {
pics[i] = BitmapFactory.decodeResource(getResources(), R.drawable.img1 + i);
// With their names, they are contiguous in the drawables index
pics[i] = Bitmap.createScaledBitmap(pics[i], 100, 100, false);
}
In your onDraw method:
for (int i = 0; i < 3; i++)
canvas.drawBitmap(pics[i], (100 * i + spaceBetweenPics * i), 0, null);

Related

Android - Image coming from web service has different size on different devices

I know there are lots of question about this topic. But still I need help. I want to show my ImageView has equal width and height in my TableLayout. But on different devices I couldn't be able to do this.
Here is I get the image using URL in AsyncTask, and set the ImageView on onPostExecute method.
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
// set the imageview
bmImage.setImageBitmap(result);
}
Here is my XML file (news.xml) where my ImageView located
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:paddingEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:paddingBottom="10dp"
android:id="#+id/mylayout"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/image"
android:clickable="true"
android:background="#drawable/border"/>
<TextView
android:layout_width="match_parent"
android:layout_height="75dp"
android:maxLines="4"
android:id="#+id/text"
android:layout_below="#+id/image"
android:layout_alignEnd="#+id/image"
android:layout_alignRight="#+id/image"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</RelativeLayout>
I thought that I can create a TableLayout, and locate the View (above) inside a TableRow like, side by side 2 view.(view is above)
To do this I get the screen width and subtract the paddings and divide by 2 and give that width to the ImageView to be able to get same size for all image views.
Here is my code,
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
tableLayout = (TableLayout) view.findViewById(R.id.tableLayout);
Log.e("screenwidth",":"+screenWidth);
// here is my paddings converted to pixel and will be subtracted from screen width
int pixValue = (int) (20 * Resources.getSystem().getDisplayMetrics().density);
int imageWidthPix = ( screenWidth - pixValue ) / 2;
Log.e("imageWidthPix ",":"+imageWidthPix );
for (int i = 0; i < categoryNews.get(myString).size(); i++) {
if (i % 2 == 0) {
tr = new TableRow(getActivity());
tableLayout.addView(tr);
}
//here is where my ImageView layout (news.xml)
View oneNews = inflater.inflate(R.layout.news, null);
ImageView imageView = (ImageView) oneNews.findViewById(R.id.image);
TextView textView = (TextView) oneNews.findViewById(R.id.text);
//here I set the width as I want
imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidthPix, RelativeLayout.LayoutParams.WRAP_CONTENT));
String imagePath = "http://my.url.com/" + categoryNews.get(myString).get(i).getImagePath();
new DownloadImageTask(imageView,getActivity().getApplicationContext())
.execute(imagePath);
I got the perfect result on my phone. But on the different device which has different screen size, ImageView has spaces on top and bottom. I tried to convert nine patch chunk and convert that into again bitmap but there were no difference. If I wouldn't get the images from web service, I would put other resolution images into mipmap-hpdi, mipmap-mdpi etc folders and there would be no error. But I am getting images dynamically so how can achieve that ImageView has half of screen width?
Thanks in advance.
Here I have edited your xml
Try Linear layout with weights,change the weight according to your need, change the layout_weight to make your image view and textview smaller or larger.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:orientation="vertical"
android:id="#+id/mylayout"
android:weightSum="10">
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="3"
android:id="#+id/image"
android:src="#drawable/sd"
android:clickable="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:maxLines="4"
android:id="#+id/text"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</LinearLayout>

How to set GridView row height?

I have a GridView, and setting the number of columns and the overal width of the grid layout. Need items with 66dp x 66dp size. But somehow items are squared, but smaller the 66x66. What am I forget?
int zz = .. // number of columns comes from outside
gridview.setNumColumns(zz);
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams)gridview.getLayoutParams();
linearParams.width=66*zz;
gridview.setLayoutParams(linearParams);
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:columnWidth="66dp"
android:gravity="center"
android:horizontalSpacing="0dp"
android:scrollbarAlwaysDrawHorizontalTrack="true"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbars="horizontal"
android:stretchMode="none"
android:verticalSpacing="0dp">
</GridView>
item prototype
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="66dp" android:layout_height="66dp">
<ImageView
android:id="#+id/icon"
android:layout_width="66dp"
android:layout_height="66dp"
android:padding="0dp"
android:background="#android:color/holo_orange_light"/>
</RelativeLayout>
shreen shot
You can Use This..
int width = 66*zz;
view.setLayoutParams(new GridView.LayoutParams(GridView.width, YOUR_HEIGHT));
LinearLayout.LayoutParams require value in pixel not dp
int gridItemWithInDp = 66;
int gridItemWithInPx = (int) (gridItemWithInDp * Resources.getSystem().getDisplayMetrics().density);
linearParams.width=gridItemWithInPx *zz;
gridview.setLayoutParams(linearParams);
You should set the width of gridview in dp either from code or from declared into resource xml
from code:
final float density = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) ((66 * zz) * density + 0.5f);
or from xml
int pixels = getResources().getDimensionPixelSize(R.dimen.example_dimen);
gridview.setNumColumns(zz);
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams)gridview.getLayoutParams();
linearParams.width=pixels;
gridview.setLayoutParams(linearParams);
Set item prototype width and height MATCH_PARENT
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="#+id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:background="#android:color/holo_orange_light"/>
</RelativeLayout>

How to set weight for width and height?

I need to create view dynamical with width and height which are the percent of parent size.So I need to add weight for width and height for one view.
Is it possible?
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:weightSum="4"
android:orientation="horizontal">
<ImageView
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:gravity="center"
android:id="#+id/imgtype"
android:scaleType="fitCenter"/>
<TextView
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="3"
android:id="#+id/txtsubject"
android:textStyle="bold"
android:textSize="#dimen/lat_sub_text_size"
android:textColor="#android:color/black"/>
<LinearLayout/>
here you will be able to divide the major portion of parent linearlayout's width to the textview and remaining minor part for imageview this is for aligning horizontally the same can be done for vertical as well.Weightsum property of parent decides number of parts it will contain.
For example, I have the below layout:
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/ll_forImage"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/ll_forList"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
</LinearLayout>
Now, I will set width and height for each View depend on Screen width and Screen Height.
int screenWidth = dpToPx(getResources().getConfiguration().screenWidthDp);
int screenHeight = dpToPx(getResources().getConfiguration().screenHeightDp);
int ratioW = ....;//
int ratioH = ....;//
setLayoutSize(ll_forImage, screenWidth/ratioW , screenHeight/ratioH );
setLayoutSize(ll_forList, screenWidth/ratioW , screenHeight - screenHeight/ratioH );
// You can use setTranslation to translate View to expected position.
with:
private int dpToPx(int dp) {
return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}
private static void setLayoutSize(View view, int width, int height) {
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
}
Adding layout_weight is a good approach while using LinearLayout.
Remember, layout_weight works only in case of LinearLayout and cannot be used with RelativeLayout.

How write text on image in RelativeLayout while it always keeps the same position (even if image is resized)?

As the title says. I need to write some text at ImageView. For that I was advised to use RelativeLayout. BUT there is not possible to use alignParentBottom (or maybe it is but I cant use margin then).
Problem is: I need to keep text at exactly some part of image even though it is resized or it is shown on different screen resolution etc. Is that possible?
CODE:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:gravity="center" >
<!-- Speaker image -->
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:background="#ffffff"
android:src="#drawable/authorimg" />
<!-- Time -->
<TextView
android:id="#+id/timeTVid"
style="#style/TextWithShadow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="2:59" />
</RelativeLayout>
I want the TextView to be somewhere in the middle but not exactly there.
EDIT: After first response tried (not working):
Horizontal position http://i59.tinypic.com/o76omg.png
Vertical position http://i59.tinypic.com/20tf7ky.png
I want to have "Your text" to be at the same position at the picture.
I found out that this is the solution. It's a shame that XML in android does not support percentage padding/margin so you have to do it programmatically as shown below. I just got the image width, width of frame and calculated it so the text is always on the same place on the image.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
int paddingLeft;
frameHeight = imgFrameLayout.getHeight();
frameWidth = imgFrameLayout.getWidth();
imgWidth = image.getWidth();
imgHeight = image.getHeight();
// getting the difference of img width and frame width
int diff = frameWidth - imgWidth;
// if frame is bigger than image then set additional value to padding
// 20% image width + (diff/2)
if (diff > 0) {
paddingLeft = imgWidth / 100 * 20 + diff / 2;
}
// else set padding 20% of the image
else {
paddingLeft = imgWidth / 100 * 20;
}
timeTV.setPadding(paddingLeft, 0, 0, 0);
}
Use this example but it will only work for the Relativelayout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<ImageView android:id="#+id/full_image_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<TextView
android:id="#+id/myImageViewText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/myImageView"
android:layout_alignTop="#+id/myImageView"
android:layout_alignRight="#+id/myImageView"
android:layout_alignBottom="#+id/myImageView"
android:layout_margin="1dp"
android:gravity="center"
android:text="Your Text"
android:textColor="#000000" />
Might want to try using a FrameLayout. In any event, set textview to match_parent (both ways)
use android:gravity="center" (not layout_gravity). now if you want to adjust the centered position to make it offset a bit, you can use paddingLeft, paddingTop, etc to adjust your center.
I think you should create two separate xml files. the first one for the image and 2nd one for the overlayed text. then in your activity class you should use LayoutInflater. I created an example and I hope it is what you are looking for.
JavaCode:
private ImageView imgView;
private TextView tv00, tv01, tv02, tv03;
private LayoutInflater mInflater = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_overlayed_with_text00);
imgView = (ImageView) findViewById(R.id.imgview);
tv00 = (TextView) findViewById(R.id.tv00);
tv01 = (TextView) findViewById(R.id.tv01);
tv02 = (TextView) findViewById(R.id.tv02);
tv03 = (TextView) findViewById(R.id.tv03);
//imgView.setImageBitmap(BitmapFactory.decodeFile("c:\\pic.jpg"));
imgView.setImageResource(R.drawable.pic);
mInflater = LayoutInflater.from(getApplicationContext());
View overView = mInflater.inflate(R.layout.textoverlay, null);
addContentView(overView, new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
ImageviewXML:
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.imageoverlayedwithtext00.ImageOverlayedWithText00$PlaceholderFragment" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/imgview" />
TextOverlayXML:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:id="#+id/tv00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp"
android:text="text0"/>
<TextView
android:id="#+id/tv01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp"
android:text="text1"/>
<TextView
android:id="#+id/tv02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp"
android:text="text2"/>
<TextView
android:id="#+id/tv03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp"
android:text="text3"/>
</LinearLayout>

Define maximum RelativeLayout size

I have to define 5 layouts on the screen and place them like a 3x3 grid. Layouts is empty.
At some moment I want programmatically to add some view on one layout and that view mustn't grows over allocated size of layout. In other words I want to have layout in which to put any view and it will be guaranty that it won't grows over that layout. Important note: I don't have rights to change manually size of added view, I only can to control its maximum size.
I have right now such layout:
<RelativeLayout
android:id="#+id/pluginsLayout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/mainButtons"
android:layout_below="#+id/paramsLayout">
<RelativeLayout
android:id="#+id/capturingPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="fill_horizontal|left"
android:layout_above="#+id/processingPluginLayout">
</RelativeLayout>
<RelativeLayout
android:id="#+id/processingPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="fill_horizontal|left"
android:layout_above="#+id/filterPluginLayout">
</RelativeLayout>
<RelativeLayout
android:id="#+id/filterPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="fill_horizontal|left|bottom"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true">
</RelativeLayout>
<RelativeLayout
android:id="#+id/exportPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="fill_horizontal|right"
android:layout_above="#+id/viewfinderPluginLayout">
</RelativeLayout>
<RelativeLayout
android:id="#+id/viewfinderPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="fill_horizontal|bottom|right"
android:layout_toLeftOf="#+id/filterPluginLayout"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true">
</RelativeLayout>
</RelativeLayout>
And I added new view in code:
public void addVFPluginView(View view)
{
((RelativeLayout)MainScreen.thiz.findViewById(R.id.viewfinderPluginLayout)).addView(view);
}
I expect to got like this behaviour:
But I got only this, view fill entire parent layout:
Note: I use API8 (don't have GridLayout)
u can use grid layout in API8.
I've managed to solve this issue.
The main idea was to control view's sizes by myself programmatically.
I calculate appropriate proportion for each zone and when somebody add a new view to some of this layout I check suitability of the size of this view to the allocated size of layout. If size is not suitable I modify LayoutParams for this View.
Here is the xml of empty layouts:
<RelativeLayout
android:id="#+id/pluginsLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/mainButtons"
android:layout_below="#+id/paramsLayout">
<LinearLayout
android:id="#+id/capturePluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true">
</LinearLayout>
<LinearLayout
android:id="#+id/processingPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true">
</LinearLayout>
<LinearLayout
android:id="#+id/filterPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true">
</LinearLayout>
<LinearLayout
android:id="#+id/exportPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true">
</LinearLayout>
<RelativeLayout
android:id="#+id/viewfinderPluginLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true">
</RelativeLayout>
</RelativeLayout>
And like that I manage the size of adding views:
public void addVFPluginView(View view)
{
//Get maximum width and height for such plugins
int layoutHeight = this.getViewfinderLayoutHeight();
int layoutWidth = this.getViewfinderLayoutWidth();
//Calculate appropriate size of added plugin's view
android.widget.RelativeLayout.LayoutParams viewLayoutParams = (android.widget.RelativeLayout.LayoutParams)view.getLayoutParams();
viewLayoutParams = this.getTunedRelativeLayoutParams(view, viewLayoutParams, layoutWidth, layoutHeight);
//Get fixed maximum size for this plugin type
public int getViewfinderLayoutWidth()
{
return ((RelativeLayout)MainScreen.thiz.findViewById(R.id.pluginsLayout)).getWidth()/2;
}
public int getViewfinderLayoutHeight()
{
return (int)(((RelativeLayout)MainScreen.thiz.findViewById(R.id.pluginsLayout)).getHeight()*0.7);
}
((RelativeLayout)MainScreen.thiz.findViewById(R.id.viewfinderPluginLayout)).addView(view, viewLayoutParams);
}
android.widget.RelativeLayout.LayoutParams getTunedRelativeLayoutParams(View view, android.widget.RelativeLayout.LayoutParams currParams, int goodWidth, int goodHeight)
{
int viewHeight, viewWidth;
if(currParams != null)
{
viewHeight = currParams.height;
viewWidth = currParams.width;
if(viewHeight > goodHeight || viewHeight <= 0)
viewHeight = goodHeight;
if(viewWidth > goodWidth || viewWidth <= 0)
viewWidth = goodWidth;
currParams.width = viewWidth;
currParams.height = viewHeight;
view.setLayoutParams(currParams);
}
else
{
currParams = new android.widget.RelativeLayout.LayoutParams(goodWidth, goodHeight);
view.setLayoutParams(currParams);
}
return currParams;
}
Finally, next issue is for several views with suitable sizes but in sum they're bigger than allocated size. Maybe I'll just straightly count sizes of views and if the sum with the size of next adding view will be more than allocated size I just disallow to add this view.

Categories

Resources