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;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = findViewById(R.id.iv);
final View dynamicView = ((View) findViewById(R.id.dynamicView));
final SeekBar seekbar = findViewById(R.id.simpleSeekBar);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) dynamicView.getLayoutParams();
params.setMarginStart(imageView.getWidth() * progress / 100);
dynamicView.setLayoutParams(params);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns: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">
<SeekBar
android:id="@+id/simpleSeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="300dp"
android:layout_width="300dp"
android:orientation="vertical">
<ImageView
android: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" />
<View
android: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;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = findViewById(R.id.iv);
final SeekBar seekbar = findViewById(R.id.simpleSeekBar);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
addOverlay(R.drawable.overlay, imageView, imageView.getWidth() * progress / 100);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Initial overlay
imageView.post(() -> addOverlay(R.drawable.overlay, imageView, 0));
}
private void addOverlay(int resourceId, ImageView imageView, int startMargin) {
imageView.getOverlay().clear();
Drawable drawable = ResourcesCompat.getDrawable(getResources(), resourceId, null);
drawable.setBounds(new Rect(startMargin, 0, imageView.getWidth(), imageView.getHeight()));
imageView.getOverlay().add(drawable);
}
}
res->drawable-overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white" />
</layer-list>
res->layout->activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns: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">
<SeekBar
android:id="@+id/simpleSeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android: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:
public void onProgressChanged(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(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
iv.getLayoutParams().width = 200 * progress;
iv.getLayoutParams().height= 200 * progress;
iv.setScaleType(ImageView.ScaleType.FIT_XY);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//write custom code to on start progress
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Post a Comment for "Android: Width Of ImageView Not Changing From SeekBar Listener"