Layout pixels and Canvas pixels different? - java

So, I have Framelayout witch has SurfaceView(0), and xml layout(1). My layouts height is 200px(below), and I'm drawing 200px high rectangle for testing. For some wierd reason, layout seems to take up more space tan rectangle. How could I make it so, that layout would be in rectangle, regardless of screen size or density? (I hope this not too confusing...)
Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200px"
android:orientation="horizontal"
android:id="#+id/game_ui
"
style="#style/AppTheme">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.2"
android:text="Points"
android:textSize="30sp"
android:gravity="center"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:text="500"
android:textSize="60sp"
android:gravity="center"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.2"
android:text="Time"
android:textSize="30sp"
android:gravity="center"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:text="500"
android:textSize="60sp"
android:gravity="center"/>
</LinearLayout>
Drawing a Rectangle:
Graphics g = game.getGraphics();
g.clearScreen(Color.BLACK);
g.drawRect(0, 0, wildth, 200, Color.GREEN);
//draws 200px high rectangle onto surfaceView
Result is this:
http://tinypic.com/r/sb6h55/8

Do not use hardcoded pixels in your layout or code.
Use density independent pixel (DP) in your layout.
android:layout_height="200dp"
Convert pixels in code to DP
final int height = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics());
final int width = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics());
Graphics g = game.getGraphics();
g.clearScreen(Color.BLACK);
g.drawRect(0, 0, width, height, Color.GREEN);
For more information read everything on
http://developer.android.com/guide/practices/screens_support.html#screen-independence

Related

Set max height on constraint layout

I have a listview inside constraint layout. When it has more lists, want to restrict the parent layout height. How can I set max layout height programmatically for bottom_layout? Display a maximum of 80% of device height.
This is the layout:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="#+id/try_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/primary_button"
android:minWidth="180dp"
android:text="#string/error_try_again"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ListView
android:id="#+id/instruction_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#+id/try_again"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/instruction_subtitle" />
<TextView
android:id="#+id/instruction_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="#+id/instruction_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/instruction_title"
app:layout_constraintBottom_toTopOf="#+id/instruction_subtitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Tried this solution on calling onCreate but didn't work:
private void BottomCardHeight(){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float density = metrics.density;
float device_height = metrics.heightPixels / density;
bottom_layout = findViewById(R.id.bottom_layout);
ConstraintSet set = new ConstraintSet();
set.clone(bottom_layout);
set.constrainMaxHeight(R.id.bottom_layout, (int) (device_height * 0.8));
// set.constrainHeight(R.id.bottom_layout, (int) (device_height * 0.8)); both not working
set.applyTo(bottom_layout);
//ConstraintLayout mConstrainLayout = (ConstraintLayout) findViewById(R.id.bottom_layout);
//ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams) mConstrainLayout.getLayoutParams();
//lp.matchConstraintMaxHeight = (int) (device_height * 0.8);
//mConstrainLayout.setLayoutParams(lp);
}
You can you do this on layout by wrapping the ConstraintLayout in another one that has a height that matches the screen height.
Then add the below constraints to the inner ConstraintLayout to get a max height of 80% of the total screen height. This requires to have a height that match constraints
android:layout_height="0dp"
app:layout_constraintHeight_max="wrap"
app:layout_constraintHeight_percent="0.8"
So, the outer layouts would be:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_max="wrap"
app:layout_constraintHeight_percent="0.8"
app:layout_constraintStart_toStartOf="parent">
<!-- other views -->
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Expand layout_weight with animation from 0.3 to 0.8

I have fragment who slide up to 0.3 of height of screen...
now i want to animate it from 0.3 to 0.8 on button. But how do it? Can I animate a layout_weight? I need show more information after click on buton that why to rise height. objectAnimator didnt work.
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1"
android:gravity="bottom">
<LinearLayout
android:id="#+id/details"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.3"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:animateLayoutChanges="true"
android:background="#drawable/shape_details"
android:clickable="true"
android:orientation="vertical"
android:padding="15dp"
android:paddingBottom="32dp"
android:paddingTop="32dp">
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text=""
android:textSize="18sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:layout_width="0dp"
android:layout_height="25dp"
android:layout_weight=".1"
android:src="#drawable/time" />
<TextView
android:id="#+id/time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".9"
android:text="TextView"
android:textColor="#android:color/darker_gray"
android:gravity="center"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
You can accomplish this by using a ValueAnimator to animate a float from 0.3 to 0.8, and then use an AnimatorUpdateListener to update the weight value in your details view's LayoutParams.
LinearLayout details = findViewById(R.id.details);
ValueAnimator animator = ValueAnimator.ofFloat(0.3f, 0.8f);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) details.getLayoutParams();
params.weight = value;
details.setLayoutParams(params);
}
});
Now you can call animator.start() whenever you want to animate the view from 30% height to 80% height.

Scale gifs to fit a horizontal ListView

I have a bunch of gifs of different sizes and I want to align then in a horizontal ListView so that they're all the same height, obviously not necessarily the same width.
We are using https://github.com/koral--/android-gif-drawable
Example:
Gif display xml
<?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"
android:background="#android:color/transparent"
android:paddingLeft="10dp"
android:id="#+id/holder"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<pl.droidsonroids.gif.GifTextureView
android:layout_width="100dp"
android:id="#+id/gif_rec_view"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
</RelativeLayout>
Container
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="#+id/title1"
android:layout_marginTop="5dp"
android:background="#android:color/transparent"
android:id="#+id/xD">
<com.devsmart.android.ui.HorizontalListView
android:id="#+id/gif_search_1"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:background="#e3e3e3"
/>
</RelativeLayout>
Load gif into view:
final GifTextureView textureView = (GifTextureView) convertView.findViewById(R.id.gif_rec_view);
LoadGif gLoad = new LoadGif(_objects.get(position).url, textureView);
gLoad.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
How would I best solve this?
Tried bunch of stuff.
//textureView.setLayoutParams(new RelativeLayout.LayoutParams(_objects.get(position).width, _objects.get(position).height));
//RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
//params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
//textureView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
Edit 1:
So looking at this thread: How to scale an Image in ImageView to keep the aspect ratio
using
android:adjustViewBounds="true"
android:scaleType="centerCrop"
worked wonders, however the images cropped like so:
and
android:adjustViewBounds="true"
android:layout_centerInParent="true"
did not work at all.
Okay so this is how I managed to solve it:
Gif display xml
<pl.droidsonroids.gif.GifTextureView
android:layout_width="150dp"
android:layout_height="match_parent"
android:id="#+id/gif_rec_view"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"
/>
Adapter
/*Absolutely fucking ridiculous*/
textureView.setLayoutParams(new RelativeLayout.LayoutParams(Utils.pxToDp(_objects.get(position).width), Utils.pxToDp(_objects.get(position).height)));
Utils ...
public static int pxToDp(int px)
{
//return (int) (px / Resources.getSystem().getDisplayMetrics().density);
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, px, Resources.getSystem().getDisplayMetrics());
}
Hope this may help some lone wanderer in the future.

The image background of my LinearLyout, containing a webview, doesn't appear

I have a fragment containing a LinearLayout containing a webview, when a change the html string in my webview, sometimes the background of my LinearLayout doesn't appear.
My fragment:
`
<ScrollView 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:scrollbarStyle="outsideOverlay"
tools:context=".NewsFragment" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#drawable/bg_item_single"
android:orientation="vertical"
android:padding="#dimen/list_margin" >
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textColor="#000"
android:textSize="20sp" />
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/transparent" />
</LinearLayout>
</LinearLayout>
</ScrollView>
`
If I have a linearLayout in a other linearLayout is just to have a space on the bottom of my scrollView, isn't the problem.
My code:
`
private void populate() {
textView.setText(grant.getName());
// Configure w`enter code here`ebview
webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webview.getSettings().setJavaScriptEnabled(false);
webview.setBackgroundColor(Color.argb(1, 0, 0, 0));
webview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
webview.loadDataWithBaseURL("file:///android_asset/", createFullHtmlPage("styles.css", grant.getGrantDescription(), 0), "text/html", "UTF-8", null);
}
`
I don't see were is the problem.
Try setting android:layout_height="wrap_content", and remove the transparent background of this view.
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/transparent" />
I fixed my problem. I used a shape as background of my LinearLayout, but if the webview is too big, for unknown reason, the shape don't work and don't appear. Therefore now I use a color background and 2 imageview for creat a bottom corner and top corner.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
tools:context=".NewsFragment" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="50dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg_item_top" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/bg_item_default"
android:orientation="vertical" >
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textColor="#000"
android:textSize="20sp" />
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/list_margin" />
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg_item_bottom" />
</LinearLayout>
</LinearLayout>
</ScrollView>
How I undestud problem is in this line
webview.setBackgroundColor(Color.argb(1, 0, 0, 0));
try this
webview.setBackgroundResource(color.blue);

new size of an image in imageView

I would like to know the new size of my image when it is set in an imageview.
I tried this :
System.out.println("Imagesize 1 w:" + imageView.getDrawable().getIntrinsicWidth()+" h "+imageView.getDrawable().getIntrinsicHeight());
System.out.println("Imagesize 2 w:" +loadedImage.getWidth()+ " h " +loadedImage.getHeight());
xml1 of imageView:
android:layout_width="fill_parent"
android:layout_height="fill_parent"
I have this result
Imagesize 1 w:400 h 577
Imagesize 2 w:400 h 577
xml2 of imageView:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Same result:
Imagesize 1 w:400 h 577
Imagesize 2 w:400 h 577
Obviously my image is not displayed in my screen with the same size in case of xml1 and xml2. I guess when I getWidth or getHeight it is the real size of the image, but I would like the size of the image displayed on my screen.
Any ideas?
Update 1:
I forgot to say that loadedImage is the bitmap of my image
Update 2:
xml.
<?xml version="1.0" encoding="utf-8"?>
<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:padding="1dip" >
<ImageView
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:contentDescription="#string/descr_image"
android:layout_alignParentBottom="true" />
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
To get the size of screen objects after they have been created you need to use a view observer like so:
ViewTreeObserver viewTreeObserver = YOURLAYOUT.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
YOURLAYOUT.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//do some things
//YOURLAYOUT.getWidth() should give a correct answer
}
});
}

Categories