I have a seekbar that changes the alpha of an ImageView. This works very smooth on an old HTC Desire 200 with android 4.0.3. I tried to run the same code on a Motorola Moto G 2014 that has android 4.4.4. The Motorola phone is 3 times more powerfull than the HTC, but when I use the seekbar the application stutters.
The problem is not with the phone, in the Antutu benchmark the Motorola phone got 18000 points, while the HTC got 6000 points.
Here is the seekbar change event:
int counter = 0;
private void mainSeekBarProgreessChanges(SeekBar seekBar, int progress) {
float a = progress / 100f;
imgRight.setAlpha(a);
++counter;
txtMsg.setText(Integer.toString(counter));
}
The stutter only appears with bigger pictures (1280x720 or bigger).With small pictures there is no stutter.
There is also stutter when I set the margins of a view with the seekbar.
Here is the manifest of the app:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testprog1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And here is the activity:
<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.testprog1.MainActivity" >
<FrameLayout
android:id="@+id/layout_top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/layout_footer"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="true" >
<ImageView
android:id="@+id/img_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/start_image_left" />
<ImageView
android:id="@+id/img_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/start_image_right" />
</FrameLayout>
<LinearLayout
android:id="@+id/layout_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="false"
android:orientation="vertical" >
<SeekBar
android:id="@+id/seekbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="100" />
<LinearLayout
android:id="@+id/layout_line1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:id="@+id/txt_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
UPDATE: If I disable hardware acceleration in the manifest then the performance somewhat improves, but there is still noticeable stutter.
UPDATE 2: Here is a screenshot when I set the margin of the ImageViews with the seekbar:
And here is a screenshot where I set the alpha of the ImageViews with setImageAlpha:
And here is the code that is called in the seekbar change event that sets the margins:
FrameLayout.LayoutParams layoutParamLeft = (LayoutParams) layoutLeft.getLayoutParams();
layoutParamLeft.setMargins(layoutParamLeft.leftMargin, layoutParamLeft.topMargin, seekBar.getMax() - progress, layoutParamLeft.bottomMargin);
layoutLeft.setLayoutParams(layoutParamLeft);
layoutLeft.invalidate();
FrameLayout.LayoutParams layoutParamRight = (LayoutParams) layoutRight.getLayoutParams();
layoutParamRight.setMargins(progress, layoutParamRight.topMargin, layoutParamRight.rightMargin, layoutParamRight.bottomMargin);
layoutRight.setLayoutParams(layoutParamRight);
layoutRight.invalidate();
It's well known that there are performance problems related to setAlpha()
. See for example:
View.setAlpha()
, a G+ post by Roman Nurik.Since it's an ImageView
widget, Have you tried using setImageAlpha()
(API level 16+) instead?
Testing your example in a Nexus 5 (with Android 5.0) I get:
setAlpha()
-- ~45mssetImageAlpha()
-- ~5msbut no noticeable stutter either way (and moving the SeekBar is completely smooth).
My use case was to fade out a view's background. I kept a reference to the view's background drawable and use its Drawable.setAlpha()
method.
This proves to quite rapid on my reference phone (Galaxy S3) versus using View.setAlpha(0-1)
, which is slow as balls, and ImageView.setImageAlpha(0-255)
, which didn't appear to have any effect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With