您可以以编程方式创建随时间改变渐变级别的东西,但这需要一些努力。或者,您可以使用 TransitionDrawable 在不同渐变之间淡入淡出,这应该会产生类似的效果。
这可以如下实现:
<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- use two gradients, extending from opposite sides of the page-->
<item android:drawable="@drawable/gradientLeft" />
<item android:drawable="@drawable/gradientRight" />
</transition>
然后,您可以在代码中激活转换,如下所示:
TransitionDrawable transition = (TransitionDrawable) myLayout.getBackground();
transition.startTransition(1500);
显然,您可能需要花一些时间才能让它看起来像您想要的那样,但这比硬编码过渡算法要容易得多!
下面是完整且可工作的代码
所以,我的想法实现了,它看起来棒极了!没想到它会这么好看,但真的很酷。我很无聊,所以决定把整个东西塞进一个函数中,这样你(和其他人)更容易使用。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView image = (ImageView) findViewById(R.id.background);
Drawable backgrounds[] = new Drawable[3];
backgrounds[0] = ContextCompat.getDrawable(this, R.drawable.gradient1);
backgrounds[1] = ContextCompat.getDrawable(this, R.drawable.gradient2);
backgrounds[2] = ContextCompat.getDrawable(this, R.drawable.gradient3);
Crossfade(image, backgrounds, 10000);
}
public void Crossfade(final ImageView image, final Drawable layers[], final int speedInMs) {
class BackgroundGradientThread implements Runnable {
Context mainContext;
TransitionDrawable crossFader;
boolean first = true;
BackgroundGradientThread(Context c) {
mainContext = c;
}
public void run() {
Handler mHandler = new Handler(mainContext.getMainLooper());
boolean reverse = false;
while (true) {
if (!reverse) {
for (int i = 0; i < layers.length - 1; i++) {
Drawable tLayers[] = new Drawable[2];
tLayers[0] = layers[i];
tLayers[1] = layers[i + 1];
final TransitionDrawable tCrossFader = new TransitionDrawable(tLayers);
tCrossFader.setCrossFadeEnabled(true);
Runnable transitionRunnable = new Runnable() {
@Override
public void run() {
image.setImageDrawable(tCrossFader);
tCrossFader.startTransition(speedInMs);
}
};
mHandler.post(transitionRunnable);
try {
Thread.sleep(speedInMs);
} catch (Exception e) {
}
}
reverse = true;
}
else if (reverse) {
for (int i = layers.length - 1; i > 0; i--) {
Drawable tLayers[] = new Drawable[2];
tLayers[0] = layers[i];
tLayers[1] = layers[i - 1];
final TransitionDrawable tCrossFader = new TransitionDrawable(tLayers);
tCrossFader.setCrossFadeEnabled(true);
Runnable transitionRunnable = new Runnable() {
@Override
public void run() {
image.setImageDrawable(tCrossFader);
tCrossFader.startTransition(speedInMs);
}
};
mHandler.post(transitionRunnable);
try {
Thread.sleep(speedInMs);
} catch (Exception e) {
}
}
reverse = false;
}
}
}
}
Thread backgroundThread = new Thread(new BackgroundGradientThread(this));
backgroundThread.start();
}
}
activity_main.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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<ImageView android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/gradient2"
android:scaleType="fitXY"/>
<TextView android:text="Hello World!" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
gradient1/2.jpg
这里的主要函数创建一个新线程,它将自动开始来回移动两个图像。一旦完成一个完整的过渡,它将开始淡入原始图像。大多数情况下,它会产生非常流畅和流畅的效果,但在组合一些渐变可绘制对象时可能看起来很奇怪。函数如下所示:
public void Crossfade(final ImageView image, final Drawable layers[], final int speedInMs)
1) final ImageView image
第一个参数应该是代表背景的图像对象。
2) final Drawable layers[]
第二个参数接受一个drawables数组,应该是两个图像,就像我上面展示的那样。玩弄不同的渐变图像很有趣,观察颜色如何“流动”也很有趣。不过请注意您的图片大小,因为我最初使用的大量图片会导致应用程序崩溃或在动画过程中严重卡顿。
3) final int speedInMs
最后一个参数仅表示从第一个可绘制对象完全过渡到第二个绘制对象所需的时间(以毫秒为单位)。
这是这两张图片以 5000 毫秒的速度交叉淡入淡出的 GIF(注意:我无法在此处放置 10 秒的 GIF 来展示整个过渡,但它非常流畅!):
Github Link To Repository
编辑 2: 我更新了 Github 和这里的函数,但我只是添加了多可绘制支持,因此可以添加任意数量的图像数组,它会循环遍历它们按时间顺序,直到到达终点,它会反转并重复。性感。