Android: Width Of Imageview Not Changing From Seekbar Listener
I am creating a simple Android app, in which the user can drag a SeekBar to the left to reveal less of an image, and right to reveal more of an image. This is accomplished through
Solution 1:
This could be done with an additional View
on top of the layout hierarchy with the same size as ImageView
. We dynamically change the top View startMargin
to have an image revealing/hiding effect.
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
publicclassMainActivityextendsAppCompatActivity {
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
finalImageViewimageView= findViewById(R.id.iv);
finalViewdynamicView= ((View) findViewById(R.id.dynamicView));
finalSeekBarseekbar= findViewById(R.id.simpleSeekBar);
seekbar.setOnSeekBarChangeListener(newSeekBar.OnSeekBarChangeListener() {
@OverridepublicvoidonProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
ConstraintLayout.LayoutParamsparams= (ConstraintLayout.LayoutParams) dynamicView.getLayoutParams();
params.setMarginStart(imageView.getWidth() * progress / 100);
dynamicView.setLayoutParams(params);
}
@OverridepublicvoidonStartTrackingTouch(SeekBar seekBar) {
}
@OverridepublicvoidonStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#ffffff"android:gravity="center"android:orientation="vertical"><SeekBarandroid:id="@+id/simpleSeekBar"android:layout_width="match_parent"android:layout_height="wrap_content" /><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_height="300dp"android:layout_width="300dp"android:orientation="vertical"><ImageViewandroid:id="@+id/iv"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="matrix"android:src="@drawable/owl"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Viewandroid:id="@+id/dynamicView"android:layout_width="0dp"android:layout_height="match_parent"android:background="@color/white"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout></LinearLayout>
Code: https://github.com/dautovicharis/sos_android/tree/q_68375499
Additional:
- Instead of px use dp in layouts
- My suggestion is to switch to Kotlin
- ConstraintLayout is a better option if you want to have better performance and avoid nested views
EDIT: I was not happy with the first solution and did a small research. A better way is to do it using ImageView overlay.
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.res.ResourcesCompat;
publicclassMainActivityextendsAppCompatActivity {
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
finalImageViewimageView= findViewById(R.id.iv);
finalSeekBarseekbar= findViewById(R.id.simpleSeekBar);
seekbar.setOnSeekBarChangeListener(newSeekBar.OnSeekBarChangeListener() {
@OverridepublicvoidonProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
addOverlay(R.drawable.overlay, imageView, imageView.getWidth() * progress / 100);
}
@OverridepublicvoidonStartTrackingTouch(SeekBar seekBar) {
}
@OverridepublicvoidonStopTrackingTouch(SeekBar seekBar) {
}
});
// Initial overlay
imageView.post(() -> addOverlay(R.drawable.overlay, imageView, 0));
}
privatevoidaddOverlay(int resourceId, ImageView imageView, int startMargin) {
imageView.getOverlay().clear();
Drawabledrawable= ResourcesCompat.getDrawable(getResources(), resourceId, null);
drawable.setBounds(newRect(startMargin, 0, imageView.getWidth(), imageView.getHeight()));
imageView.getOverlay().add(drawable);
}
}
res->drawable-overlay.xml
<?xml version="1.0" encoding="utf-8"?><layer-listxmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:drawable="@color/white" /></layer-list>
res->layout->activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#ffffff"android:gravity="center"android:orientation="vertical"><SeekBarandroid:id="@+id/simpleSeekBar"android:layout_width="match_parent"android:layout_height="wrap_content" /><ImageViewandroid:id="@+id/iv"android:layout_width="300dp"android:layout_height="300dp"android:scaleType="matrix"android:src="@drawable/owl"
/></LinearLayout>
Code: https://github.com/dautovicharis/sos_android/commits/q_68375499_v2
EDIT: Final solution and what Adam actually wanted to achieve is:
Code:https://github.com/dautovicharis/sos_android/tree/q_68375499_v3
Solution 2:
publicvoidonProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
iv.getLayoutParams().width = 300 * progress/100;
iv.drawableStateChanged(); //<--- You need to redraw it after you change it.
System.out.println(300 * progress/100);
}
Solution 3:
seekbar.setOnSeekBarChangeListener(newSeekBar.OnSeekBarChangeListener() {
@OverridepublicvoidonProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
iv.getLayoutParams().width = 200 * progress;
iv.getLayoutParams().height= 200 * progress;
iv.setScaleType(ImageView.ScaleType.FIT_XY);
}
@OverridepublicvoidonStartTrackingTouch(SeekBar seekBar) {
//write custom code to on start progress
}
@OverridepublicvoidonStopTrackingTouch(SeekBar seekBar) {
}
});
Post a Comment for "Android: Width Of Imageview Not Changing From Seekbar Listener"