So I've read quite a few questions on here as well as tried lots of stuff to try to get this to work. I'm either misunderstanding all of the examples I've read or am looking at the wrong stuff.
What I'm trying to do is set up a relative layout within a relative layout that contains an image view. I want to be able to have the relative layout match the size of the imageview (which I want scaled based on specific screen size) to keep a constant square size. This view will contain buttons as well.When I run the below code I get a square for the image view but the buttons are displayed on the top of the screen. So it appears to me that the imageview is properly scaling down into a square but the layout itself is still matching the overall screen size. I have an XML file set up as follows:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:id="#+id/layout_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
>
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="#drawable/bg" />
<Button
android:id="#+id/button_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_one" />
....
</RelativeLayout>
</RelativeLayout>
Java code below:
public class MainActivity extends ActionBarActivity {
RelativeLayout layoutTwo, mainLayout;
Button buttonOne, buttonTwo, buttonThree, buttonFour, buttonFive;
Button buttonSix, buttonSeven, buttonEight, buttonNine;
ImageView scalingBackground;
int screenWidth, screenHeight, finalSquare;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
layoutTwo = (RelativeLayout) findViewById(R.id.layout_two);
scalingBackground = (ImageView) findViewById(R.id.image_view);
initializeButtons();
squareBackground();
}
private void squareBackground() {
screenWidth = mainLayout.getLayoutParams().width;
scalingBackground.getLayoutParams().height = screenWidth;
scalingBackground.getLayoutParams().width = screenWidth;
layoutTwo.getLayoutParams().height = screenWidth;
layoutTwo.getLayoutParams().width = screenWidth;
}
Not quite sure whats going on here, I'd appreciate a kick in the right direction. Thanks
You can use a custom imageview in which height and width are same.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:id="#+id/layout_two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
>
<com.packagename.SquareImageView
android:id="#+id/image_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="#drawable/bg" />
<Button
android:id="#+id/button_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_one" />
....
</RelativeLayout>
</RelativeLayout>
Create a class for custom imageview.
public class SquareImageView extends ImageView {
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
}
Related
I want to make my ImageView's size is rectangle shaped based on its width and it's done with overiding onGlobalLayout() and put photo.getWidth(). But it is only work in portrait screen, and no in landscape screen.
Portrait is works fine :
In landscape, the image not rectangle shaped
And this is the code :
fragment_productdetail.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal">
<ImageView
android:id="#+id/ivImage0"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="3dp"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:src="#drawable/noimage"/>
<ImageView
android:id="#+id/ivImage1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="3dp"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:src="#drawable/noimage"/>
<ImageView
android:id="#+id/ivImage2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="3dp"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:src="#drawable/noimage"/>
<ImageView
android:id="#+id/ivImage3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="3dp"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:src="#drawable/noimage"/>
</LinearLayout>
FragmentProductDetail.java
ivPhotos[0] = (ImageView) inflatedView.findViewById(R.id.ivImage0);
ivPhotos[1] = (ImageView) inflatedView.findViewById(R.id.ivImage1);
ivPhotos[2] = (ImageView) inflatedView.findViewById(R.id.ivImage2);
ivPhotos[3] = (ImageView) inflatedView.findViewById(R.id.ivImage3);
for (final ImageView photo : ivPhotos) {
photo.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
photo.getViewTreeObserver().removeOnGlobalLayoutListener(this);
photo.getLayoutParams().height = photo.getWidth();
}
});
}
Then i try put Log.i("zihad", ""+photo.getWidth()); inside onGlobalLayout() to get the width in landscape, then it gives me same value of width in portrait. So what should i do to make it works in portrait and landscape?
*sorry for bad english, i ask here also to improve my english
Quick Tip:
I am not sure, if this is what you want. From what I assume, I think you might require a layout with Square ImageView. If you are trying to change the layout after rendering it, you should call photo.requestLayout(); before setting its height.
An alternative solution would be to use a SquareImageView. To achieve this, just create a View which extends ImageView and set the height by overriding its onMeasure like this.
public class MyImageView extends ImageView {
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
Now in your layout, substitute ImageView for MyImageView(with complete package name).
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>
Normally my gui look like below
I tried to implement same size for width and height in Get button. But the result is unfair (see the image below)
code snippet i tried
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spinner);
spinner = (Spinner)findViewById(R.id.spinner1);
spinner.setAdapter(new MyAdapter(this, R.layout.row, strings));
Button btn = (Button)findViewById(R.id.getbtn);
int x = btn.getLayoutParams().height;
btn.getLayoutParams().width = x;
}
xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Testing"
/>
<Spinner
android:id="#+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="#string/prompt"/>
<Button
android:id="#+id/getbtn"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="Get"
/>
</LinearLayout>
</LinearLayout>
How to solve this issue ?
Thanks in advance.
You are giving fill_parent to the android:layout_height attribute to the Button XML. So, when you programmtically set that height value to width of Button then the Button taking so large width to fill the parent width.
Now, change the following attribute of Button
android:layout_height="fill_parent"
to
android:layout_height="wrap_content"
you can create custom button, overriding onMeasure() as below:
public class SquareHeightButton extends Button {
...
...
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}
}
IMPORTANT:
I want to draw content of a View A to a bitmap and part of the View A is a TextView which text has to be centered horizontally. The View A is not displayed nor is part of another View.
QUESTION:
How can I tell the TextView to display the text correctly when it is drawn to a bitmap????
My base layout(base_layout.xml):
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false" >
<TextView
android:id="#+id/dateTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="5dp"
android:gravity="center"
android:padding="3dp"
android:textStyle="bold" />
<TextView
android:id="#+id/shiftsListTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:singleLine="false"
android:maxLines="2"
android:padding="3dp" />
</LinearLayout>
My TestActivity.java activity, which I use for testing:
public class TestActivity extends Activity {
private LinearLayout mainHolderLL;
#Override
protected int getLayoutXml() {
return R.layout.activity_test;
}
#Override
protected final void onCreate(Bundle savedInstanceState) {
mainHolderLL = (LinearLayout) findViewById(R.id.mainHolderLL);
View baseLayoutView = View.inflate(context, R.layout.base_layout, null);
dateTV.setText("Feb 2014");
shiftsListTV.setText("shift1, shift2");
int width = 500;
int height = 500;
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
baseLayoutView.measure(widthMeasureSpec, heightMeasureSpec);
baseLayoutView.layout(0, 0, baseLayoutView.getMeasuredWidth(), baseLayoutView.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(baseLayoutView.getMeasuredWidth(), baseLayoutView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
baseLayoutView.draw(canvas);
ImageView appwidget_image_view = (ImageView) findViewById(R.id.appwidget_image_view);
appwidget_image_view.setImageBitmap(bitmap);
}
}
activity_test.xml:
<HorizontalScrollView 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" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/mainHolderLL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="#dimen/common_padding_normal" >
<ImageView
android:id="#+id/appwidget_image_view"
android:layout_width="294dp"
android:layout_height="294dp"
android:background="#android:color/black"
android:cropToPadding="false"
android:padding="#dimen/widget_margin"
android:scaleType="fitXY"
tools:ignore="ContentDescription" />
</LinearLayout>
</ScrollView>
</HorizontalScrollView>
If the bitmap is displayed inside a ImageView, the text inside dateTV TextView is not centered horizontally and it looks as crushed(on Android 4.3 but on Android 2.3.3 nothing is displayed), but the text inside shiftsListTV is displayed correctly.
If I remove the android:gravity attribute from dateTv TextView the text inside dateTV is displayed correctly but is not centered. I need the text centered.
Edit:
After some research I found out that TextView has a problem with gravity tag.
The imageview is NOT important it is solely for displaying the bitmap.
My base layout is a ListView of LinearLayouts, and each item in the grid is the FrameLayout below. I am downloading an image to the ImageView. Prior to the image being loaded, there is no content and the layout is shrunk to the height of the small ProgressBar (first problem), when I expect it to be 240dp or 120dp. After the image is placed in the view, the layout does not adjust (second problem) and the height remains the shrunken dimension of a small ProgressBar.
loading image code:
#Override
public View getView(View convertView) {
// ...
// set up holder
// ...
new GetPhotoTask().execute(holder.my_tile_image, holder.my_loading, my_media_url);
holder.my_tile_image.setVisibility(View.INVISIBLE);
holder.my_loading.setVisibility(View.VISIBLE);
holder.my_tile_label.setText(activityObject1.track.name);
// ...
}
private final class GetPhotoTask extends AsyncTask<Object, Void, Drawable> {
ImageView iv;
ProgressBar pb;
#Override
protected Drawable doInBackground(Object... params) {
iv = (ImageView) params[0];
pb = (ProgressBar) params[1];
return new BitmapDrawable(getResources(), loadAsset(params[2]).media_url, true));
}
#Override
protected void onPostExecute(Drawable result) {
super.onPostExecute(result);
pb.setVisibility(View.GONE);
iv.setImageDrawable(result);
iv.setVisibility(View.VISIBLE);
}
}
the main xml:
<ListView
android:id="#+id/my_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dp" />
the xml for each row:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_row_type_3"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="240dp"
android:weightSum="3" >
<include layout="#layout/my_tile_layout"
android:id="#+id/my_tile_1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
<LinearLayout
android:id="#+id/my_row_type_2"
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="2" >
<include layout="#layout/my_tile_layout"
android:id="#+id/my_tile_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<include layout="#layout/my_tile_layout"
android:id="#+id/my_tile_3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
the xml for row content:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_tile_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dp" >
<ImageView
android:id="#+id/my_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:contentDescription="#string/foo" />
<ProgressBar
android:id="#+id/my_loading"
style="?android:attr/progressBarStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<TextView
android:id="#+id/my_tile_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/my_title"
android:layout_gravity="left|bottom" />
</FrameLayout>
Why does the initial layout shrink to the height of progress bar even though I've hard coded 240dp for each row? Why does setting a bitmap in the ImageView content not cause it to resize at that point either? The first question most important, as I believe it will nullify the second. Thanks in advance.
SOLUTION
To get the structure I want, I use RelativeLayout for the tiles (for layering ability), and for each row I am overriding the LinearLayout to enforce the sizing I want set for each row. As there is a potential for each tile's content to be larger or smaller than the view, this is screwing up my ability to rely on either centerCrop or fitCenter. So in my custom layout, I set the height to be proportional to the width of each row, and the mode of the MeasureSpec to be EXACTLY.
public final class MyRow3 extends LinearLayout {
// ...
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, makeMeasureSpec(getSize(widthMeasureSpec) * 2 / 3, MeasureSpec.EXACTLY));
}
I'm not sure why it isn't honouring it but why not do something like this instead:
Set an absolute height in your ImageView to guarantee some space.
<ImageView
android:layout_height="###dp"
/>
Then change the layout back to an auto adjusted state just before the image is loaded:
iv.setLayoutParams( new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT ) );
To get the structure I want, I use RelativeLayout for the tiles (for layering ability), and for each row I am overriding the LinearLayout to enforce the sizing I want set for each row. As there is a potential for each tile's content to be larger or smaller than the view, this is screwing up my ability to rely on either centerCrop or fitCenter. So in my custom layout, I set the height to be proportional to the width of each row, and the mode of the MeasureSpec to be EXACTLY.
public final class MyRow3 extends LinearLayout {
// ...
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, makeMeasureSpec(getSize(widthMeasureSpec) * 2 / 3, MeasureSpec.EXACTLY));
}