I have the following fragment. No matter what I do but the image is not visible in the Image View-: For testing I put the button on fragment but that is refelected but image is not visible
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.transenigma.iskconapp.DynamicImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/img2"
android:id="#+id/myAboutImg" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="8dp"
tools:text="Text"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_gravity="center_horizontal|bottom" />
<!--</android.support.v7.widget.CardView>-->
</FrameLayout>
I have made the following class that extends ImageView-:
package com.transenigma.iskconapp;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class DynamicImageView extends ImageView {
public DynamicImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final Drawable d = this.getDrawable();
if (d != null) {
// ceil not round - avoid thin vertical gaps along the left/right edges
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
this.setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
What did you want to do in your DynamicImageView?
You can try to delete the method onMeasure,and see the difference between them.
Maybe the mistake is in your onMeasure.
Related
I'm trying to create an app for drawing some simple lines in a canvas. I want the canvas to take up the top 50% of the screen, leaving the bottom 50% of the screen for buttons and what not. I am currently using setContentView(canvas); which makes it so that the canvas takes up 100% of the screen.
You can create a class that extends View and do drawing inside that view on onDraw() method of that view. Add that view to your layout with any width or height you choose.
Instead of setContentView, use your layout XML to create a view to hold the canvas as shown in Error referencing an inner class View in layout/main.xml.
After that, it's a matter of using a technique in android:layout_height 50% of the screen size such as:
<LinearLayout ...>
<view
class="com.example.foo.FooActivity$Drawer"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
>
</LinearLayout>
You can also use, say, android:layout_weight="0.7" and "0.3" to set the canvas/button container to 70% and 30% of the screen respectively.
Here's a minimal, complete example:
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:keepScreenOn="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#f00"
>
<view
class="com.example.foo.FooActivity$Drawer"
android:background="#00f"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<LinearLayout
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
>
<Button
android:id="#+id/start"
android:text="#string/start"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#f0f"
android:padding="10dp"
android:layout_margin="20dp"
/>
<Button
android:id="#+id/stop"
android:text="#string/stop"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#f0f"
android:padding="10dp"
android:layout_margin="20dp"
/>
</LinearLayout>
</LinearLayout>
Activity:
package com.example.foo;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
public class FooActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foo);
}
public static class Drawer extends View {
private static Paint paint;
private static int viewWidth;
private static int viewHeight;
public Drawer(Context con, AttributeSet attr) {
super(con, attr);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
}
// https://stackoverflow.com/a/9718512/6243352
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
#Override
protected void onDraw(final Canvas c) {
super.onDraw(c);
paint.setARGB(255, 0, 0, 0);
int cx = viewWidth / 2;
int cy = viewHeight / 2;
c.drawCircle(cx, cy,viewWidth / 4, paint);
}
}
}
Result:
I created a new small example to explain my new problem. In the example I created a RelativeLayout that fills the whole screen. And 3 children :
Custom view (PView) created to draw proportional view that must fill all free space by width in portrait mode and free space by height in landscape mode without overlay on top and bottom of FrameLayout (pink)
FrameLayout with id top that must show above middle (red)
FrameLayout with id bottom that must show below middle (yellow)
But now in landscape mode middle item overdraw top and bottom. Have anyone idieas how to fix it ?
layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/top"
android:layout_width="100dp"
android:layout_height="24dp"
android:layout_above="#+id/middle"
android:layout_centerHorizontal="true"
android:background="#FFFF0000" />
<test.com.heighttest.PView
android:id="#+id/middle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="#FFFF00FF" />
<FrameLayout
android:id="#+id/bottom"
android:layout_width="100dp"
android:layout_height="24dp"
android:layout_below="#+id/middle"
android:layout_centerHorizontal="true"
android:background="#FFFFFF00" />
</RelativeLayout>
PView.java
package test.com.heighttest;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/**
* Created by Anton Potekhin (Anton.Potekhin#gmail.com) on 26.09.16.
*/
public class PView extends RelativeLayout {
public static final int USE_FOR_SCALE_WIDTH = 0;
public static final int USE_FOR_SCALE_HEIGHT = 1;
public int getUseForScale() {
return useForScale;
}
public void setUseForScale(int useForScale) {
this.useForScale = useForScale;
}
private int useForScale = 0;
public float getAspectRatio() {
return aspectRatio;
}
public void setAspectRatio(float aspectRatio) {
this.aspectRatio = aspectRatio;
}
/**
* Aspect ratio to calculate size of view. Set 0 to not use aspect ratio (Works like RelativeLayout).
*/
private float aspectRatio = 0;
public PView(Context context) {
super(context);
}
public PView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Use aspect ratio only if it more than 0
if (aspectRatio > 0) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (useForScale == USE_FOR_SCALE_WIDTH) {
height = Math.round(width / aspectRatio);
} else {
width = Math.round(height * aspectRatio);
}
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
MainActivity.java
package test.com.heighttest;
import android.content.res.Configuration;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private PView middleView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
com.facebook.stetho.Stetho.initializeWithDefaults(this);
setContentView(R.layout.activity_main);
middleView = (PView) findViewById(R.id.middle);
middleView.setAspectRatio(1.2f);
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
middleView.setUseForScale(PView.USE_FOR_SCALE_HEIGHT);
} else {
middleView.setUseForScale(PView.USE_FOR_SCALE_WIDTH);
}
}
}
Screenshot in portrait mode (Works correctly):
Screenshot in landscape mode (Works incorrect because middle overdraw top and bottom):
Screenshot what i want to get in landscape mode
Solution by #nidhi-pandya (with my fixes):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:id="#+id/top"
android:layout_width="100dp"
android:layout_height="24dp"
android:background="#FFFF0000" />
<test.com.heighttest.PView
android:id="#+id/middle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFFF00FF" />
<FrameLayout
android:id="#+id/bottom"
android:layout_width="100dp"
android:layout_height="24dp"
android:background="#FFFFFF00" />
</LinearLayout>
</RelativeLayout>
Add LinearLayout below Relativelayout and use its orientation to arrange your content vertically. Use alignparenttop, alignparentbottom and centerinparent attribute. It will give you the same output in both orientation.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:id="#+id/top"
android:layout_width="80dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:background="#FFFF0000" />
<test.com.heighttest.PView
android:id="#+id/middle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="#FFFF00FF" />
<FrameLayout
android:id="#+id/bottom"
android:layout_width="80dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:background="#FFFFFF00" />
</LinearLayout>
</RelativeLayout>
I am working on an activity where I created a custom view that I am adding dynamically within a LinearLayout. The problem is that I am unable to give margin between the custom views I add.
Here is a look at the two views I added which are next to each other.
Screentshot:
Code for creating the views dynamically:
private void AddSelectedTagUI(final com.main.feedify.serializers.Tags tag){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.tags,tags_section_selectedtags,false);
TextView tagName = (TextView)v.findViewById(R.id.customview_tags_name);
tagName.setText(tag.getTagName());
ImageView close_button = (ImageView)v.findViewById(R.id.customview_tags_close);
close_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RemoveTag(tag.getTagID(), selectedTags);
}
});
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
tags_section_selectedtags.addView(v, params);
// cast view to tags and add it in our layout.
// this will help us find out the tag we wanna delete.
view_selectedTags.add(v);
this.UpdateMessage(true);
}
tags.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:background="#drawable/tags"
android:padding="5dp"
android:id="#+id/custom_tag"
>
<TextView android:id="#+id/customview_tags_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beyonce"
android:layout_marginLeft="10dp"
android:layout_marginRight="3dp"
android:layout_centerVertical="true"
android:textColor="#android:color/white"
android:textSize="#dimen/title" />
<ImageView
android:id="#+id/customview_tags_close"
android:layout_width="wrap_content"
android:layout_marginTop="2dp"
android:layout_toRightOf="#+id/customview_tags_name"
android:layout_height="wrap_content"
android:src="#drawable/close"
android:layout_marginLeft="3dp"
android:layout_marginRight="10dp"
/>
</RelativeLayout>
activity_tags.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background">
<TextView
android:id="#+id/tags_lbl_taginfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Add at least 4 favorite topics"
android:layout_marginTop="20dp"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_below="#+id/tags_lbl_taginfo"
android:layout_width="match_parent"
android:layout_height="190dp"
android:layout_marginTop="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:id="#+id/tags_section_selectedtags">
</LinearLayout>
<EditText
android:id="#+id/tags_txt_tags"
android:layout_below="#+id/tags_section_selectedtags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:hint="Add tags ..."
android:textColor="#color/tags_edittext"
android:paddingTop="15dp"
android:singleLine="true"
android:paddingLeft="9dp"
android:paddingBottom="15dp"
android:background="#drawable/tags_edittext"
/>
<TextView
android:id="#+id/tags_lbl_tagsuggestion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Suggestions"
android:layout_marginTop="15dp"
android:layout_below="#id/tags_txt_tags"
/>
</RelativeLayout>
Custom Tags Class:
package com.main.feedify.custom_views;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.main.feedify.feedify_mockup.R;
import com.tokenautocomplete.TokenCompleteTextView;
/**
* Created by Muazzam on 10/17/2015.
*/
public class Tags extends RelativeLayout{
private com.main.feedify.serializers.Tags tag;
public Tags(Context context, AttributeSet attrs)
{
super(context, attrs);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.tags,this);
}
public void setTag(com.main.feedify.serializers.Tags t){
this.tag = t;
}
public com.main.feedify.serializers.Tags getTag(){
return this.tag;
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = 5;
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
}
You are setting margins in Pixels. Try converting them into dp, so that the margins value becomes independent of display density.
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = pxToDp(5);
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
private int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
EDIT:
Get rid of the margin code in onLayout() and set those margins, when you are puting this view inside a viewgroup like LinearLayout or RelativeLayout etc.
You should try setting the layout_margin to your RelativeLayoutin your XML file, same as you did with the padding.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:background="#drawable/tags"
android:layout_margin="5dp"
android:padding="5dp"
android:id="#+id/custom_tag">
<TextView android:id="#+id/customview_tags_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beyonce"
android:layout_marginLeft="10dp"
android:layout_marginRight="3dp"
android:layout_centerVertical="true"
android:textColor="#android:color/white"
android:textSize="#dimen/title" />
<ImageView
android:id="#+id/customview_tags_close"
android:layout_width="wrap_content"
android:layout_marginTop="2dp"
android:layout_toRightOf="#+id/customview_tags_name"
android:layout_height="wrap_content"
android:src="#drawable/close"
android:layout_marginLeft="3dp"
android:layout_marginRight="10dp" />
</RelativeLayout>
You should add left margin to view while adding it.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
//add this line
params.leftMargin=50;
//end
tags_section_selectedtags.addView(v, params);
I think that the problem lays in this piece of code:
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
int margin = 5;
margins.topMargin = 0;
margins.bottomMargin = 0;
margins.leftMargin = margin;
margins.rightMargin = 0;
setLayoutParams(margins);
};
Here you change the layout parameters inside the onLayout() method and it should lead to the infinite layout of your view: custom view's parent view calls onLayout() which calls setLayoutParams() which results in onLayout()... And so it goes.
One way to prevent this behavior is to add your margins in tags.xml file, just like you did with the paddings. The infinite layout loop will be gone and your view will have a chance to set its margins.
I have designed a view dynamically and have given parameters such like yours, have a look at this code:
https://stackoverflow.com/a/33339420/5479863
and to convert into dp from pixel use this method
private int getPixelsToDP(int dp) {
float scale = getResources().getDisplayMetrics().density;
int pixels = (int) (dp * scale + 0.5f);
return pixels;
}
I've been searching for a while now to solve this problem. I created my own GIF view. I want to resize this GIF view such that it will cover the screen width, dependent on the screen size of the actual device. I got it working so that the GIF will show in it's actual size, but for the device of my friend, it is portrayed too small. I'm using the Movie class provided by Android.
I tried adjusting the canvas but that didn't work. I also tried multiple things with the onMeasure method but they also didn't work. The closest I got was that the GIF was larger but the window in which it appeared was still the same size as before. The code of the GIF view is down below, alongside with the xml file where it is used.
<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"
android:background="#drawable/spacevert"
tools:context="com.wina.hengst.hengstdrinkinggame.Multiplayer" >
<TextView
android:id="#+id/timerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="74dp"
android:text="#string/be_ready"
android:textSize="50sp"
android:textStyle="bold" />
<LinearLayout
android:id="#+id/linear"
android:layout_below="#id/timerTextView"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.wina.hengst.hengstdrinkinggame.GIF
android:id="#+id/gif"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/linear"
android:layout_centerHorizontal="true"
android:textSize="50sp"
android:gravity="center" />
<SeekBar
android:id="#+id/sliderMulti"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<CheckBox
android:id="#+id/hiddenMulti"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_above="#id/sliderMulti"
android:text="#string/hidden"
android:textSize="25sp"
android:checked="true" />
<TextView
android:id="#+id/progress"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#id/sliderMulti"
android:textSize="25sp"
/>
<Button
android:id="#+id/startMulti"
android:text="#string/start"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_below="#id/progress"
android:background="#color/Hengstgroen"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"/>
package com.wina.hengst.hengstdrinkinggame;
import java.io.InputStream;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
public class GIF extends View {
private InputStream gifInputStream;
private Movie gifMovie;
private int movieWidth, movieHeight;
private long movieDuration;
private long mMovieStart;
public GIF(Context context) {
super(context);
init(context);
}
public GIF(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public GIF(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context){
setFocusable(true);
gifInputStream = context.getResources()
.openRawResource(R.drawable.sweetlemonade);
gifMovie = Movie.decodeStream(gifInputStream);
movieWidth = gifMovie.width();
movieHeight = gifMovie.height();
movieDuration = gifMovie.duration();
}
#Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
setMeasuredDimension(movieWidth, movieHeight);
}
public int getMovieWidth(){
return movieWidth;
}
public int getMovieHeight(){
return movieHeight;
}
public long getMovieDuration(){
return movieDuration;
}
#Override
protected void onDraw(Canvas canvas) {
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
}
if (gifMovie != null) {
int dur = gifMovie.duration();
if (dur == 0) {
dur = 1000;
}
int relTime = (int)((now - mMovieStart) % dur);
gifMovie.setTime(relTime);
gifMovie.draw(canvas, 0, 0);
invalidate();
}
}
public void restart() {
mMovieStart = 0;
}
}
Your help would be much appreciated!
EDIT
I found it was too hard to try and solve this problem. I've just converted the gif into multiple images and used an animation xml provided by android. This is something I can resize easily by adjusting the xml with the ImageView. For the conversion I used GIMP and a plugin called export layers. If any of you know the answer, you can always write the answer here and I'll try it.
Try using Glide library, it can put GIFs in ImageViews. You also need to set layout_width in your ImageView to match_parent.
https://github.com/bumptech/glide
Here is what I would like my ScrollView to look like:
The maximum size is defined with the layout_weight (so that other items below the ScrollView can be displayed properly)
If the content is smaller than that maximum size, then it just behaves as with layout_height="wrap_content"
Here is what I currently have:
<ScrollView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:measureAllChildren="true"
android:fillViewport="false"
>
I don't think the measureAllChildren really does anything at all...
If I add android:layout_weight, the size will always be what I would like the maximum to be. Without it, it just extends more than it should...
I don't mind extending the ScrollView class to change the behavior of onMeasure if I need to...?
PS: If that makes a differences, I am trying to get this working from Froyo onward.
I ended up writing my own class, extending ScrollView
Since you ask...here is the code. Probably not the cleanest but it does what I want.
Note that it expects the layout_weight to be set when the view is created and you should not set the weigthSum in the parent LinearLayout or you'll get funny things (since the weight of this one changes from the original value to 0 depending on the size of the content of the ScrollView)
First, in the layout file, the view is declared like this:
<com.matthieu.widget.ShrinkingScrollView
android:id="#+id/scroll"
android:scrollbars="vertical"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="4"
android:background="#cc0000"
>
<TextView
android:id="#+id/in_scroll_view"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="#0000bb"
/>
</com.matthieu.widget.ShrinkingScrollView>
Then the code for the widget:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.ScrollView;
public class ShrinkingScrollView extends ScrollView {
private float original_weight=-1;
public ShrinkingScrollView(Context context) {
super(context);
}
public ShrinkingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ShrinkingScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
float previous_weight = params.weight;
if (original_weight == -1)
original_weight = params.weight;
if ((getChildCount()>0) && (getVisibility()!=GONE)) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED));
int overall_height = getChildAt(0).getMeasuredHeight();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getMeasuredHeight() >= overall_height) {
if (previous_weight != 0) {
params.weight=0;
params.height = overall_height;
setLayoutParams(params);
post(new Runnable() {
public void run() {
requestLayout();
}
});
}
setMeasuredDimension(getMeasuredWidth(),overall_height);
}
else if (previous_weight == 0) {
params.weight = original_weight;
params.height = 0;
setLayoutParams(params);
post(new Runnable() {
public void run() {
requestLayout();
}
});
}
}
else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
If I understand your requirement correctly, the way I have done something like this is to place the scrollview along with anything else you want to display below it into a Relative layout. Then, in your layout file place the item on the bottom of the screen in the file first (with android:layout_alignParentBottom="true"), then put the scroll view and place it above the first item using something like:android:layout_above="#id/firstItem". Like this in which I put an image view on the bottom with a scroll view above it taking the remaining space:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/searchByNameScreen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_marginTop="1dip"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="#+id/bottomImage"
android:layout_width="fill_parent"
android:layout_height="75dip"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:paddingBottom="15dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="7dip"
android:scaleType="fitXY"
android:src="#drawable/android_450x50_moreinfo" />
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ScrollView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/bottomImage"
android:layout_marginBottom="3dip"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginTop="1dip"
android:scrollbars="none" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/aboutCopyLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/aboutTopLayer"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:background="#drawable/rounded_background"
android:gravity="center"
android:padding="5dip" >
<!-- android:background="#drawable/rounded_background" -->
<TextView
android:id="#+id/aboutCopyText"
style="#style/ResortNameExtraLine"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:text="#string/aboutCopy" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
Here another solution using sizes instead of weights. I've extended ScrollView and added code to implement this feature:
https://gist.github.com/JMPergar/439aaa3249fa184c7c0c
I hope that be useful.
JMpergar answer seems right but its not worked until I changed the onMeasure method like below.
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE
&& heightSize > maxHeight) {
heightSize = maxHeight;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
getLayoutParams().height = heightSize;
} else {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec)
, getDefaultSize(this.getSuggestedMinimumHeight(), heightMeasureSpec));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
you can just wrap your ScrollView into another ConstraintLayout, then constrain the height (the line app:layout_constrainedHeight="true"):
<!-- another constraint layout to keep ScrollView shrinking -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">