| 知乎专栏 |
全屏显示
android:scaleType="matrix"
水平居中显示 android:layout_gravity="center"
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
app:srcCompat="@drawable/niboer"
tools:ignore="MissingConstraints" />
android:scaleType="fitCenter"
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
app:srcCompat="@drawable/fo2"
tools:ignore="MissingConstraints" />
方法一
private Drawable getImageDrawableFromUrl(String url) {
try {
InputStream inputStream = (InputStream) new URL(url).getContent();
Drawable drawable = Drawable.createFromStream(inputStream, "image.jpg");
// Drawable drawable = Drawable.createFromStream(new URL(url).openStream(), "image.jpg");
// Drawable drawable = Drawable.createFromStream(getContext().getContentResolver().openInputStream(Uri.parse(url)), null);
return drawable;
} catch (IOException e) {
Log.d("VoicePopup", e.getMessage());
} catch (Exception e) {
Log.d("VoicePopup", e.getMessage());
}
return null;
}
Drawable drawable = getImageDrawableFromUrl(image);
imageView = findViewById(R.id.imageView);
imageView.setImageDrawable(drawable);
方法二
imageView = findViewById(R.id.imageView);
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream is = (InputStream) new URL(image).getContent();
final Drawable d = Drawable.createFromStream(is, null);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageDrawable(d);
}
});
} catch (Exception e) {
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream inputStream = new URL("https://img.netkiller.cn/2d/f4873238-7860-11ee-8344-0242ac12000c.png").openStream();
final Drawable drawable = Drawable.createFromStream(inputStream, null);
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageDrawable(drawable);
}
});
} catch (Exception e) {
}
}
}).start();
方法三
try {
URL url = new URL("https://img.netkiller.cn/2d/f4873238-7860-11ee-8344-0242ac12000c.png");
new Thread(new Runnable() {
@Override
public void run() {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(url.openStream());
showImg(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (MalformedURLException e) {
e.printStackTrace();
}
private void showImg(final Bitmap bitmap) {
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
参数
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item
android:drawable="@drawable/hotel1"
android:duration="150" />
<item
android:drawable="@drawable/hotel2"
android:duration="150" />
<item
android:drawable="@drawable/hotel3"
android:duration="150" />
<item
android:drawable="@drawable/hotel4"
android:duration="150" />
<item
android:drawable="@drawable/hotel5"
android:duration="150" />
</animation-list>
<ImageView
android:id="@+id/load_image"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center_vertical"
android:scaleType="centerCrop"
android:src="@drawable/loading_anim_image" />
ImageView imageView = findViewById(R.id.imageView);
animationDrawable = (AnimationDrawable) imageView.getDrawable();
//直接就开始执行,性能不是最佳的。
animationDrawable.start();
旋转 PNG 动画效果,用于显示唱片播放效果
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context="cn.netkiller.album.MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:srcCompat="@drawable/fo2"
tools:ignore="MissingConstraints" />
<cn.netkiller.album.view.SoundWaveView
android:id="@+id/sound_wave_view"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignBottom="@id/imageView"
app:layout_constraintBottom_toBottomOf="@+id/imageView" />
<ImageView
android:id="@+id/imageViewWan"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
app:layout_constraintBottom_toTopOf="@+id/sound_wave_view"
app:layout_constraintEnd_toEndOf="@+id/sound_wave_view"
app:layout_constraintStart_toStartOf="@+id/sound_wave_view"
app:srcCompat="@drawable/wan"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
创建旋转动画效果 res/anim/rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:toDegrees="359"></rotate>
</rotate>
Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate);
LinearInterpolator linearInterpolator = new LinearInterpolator();
rotateAnimation.setInterpolator(linearInterpolator);
View imageViewWan = findViewById(R.id.imageViewWan);
imageViewWan.startAnimation(rotateAnimation);
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<ImageView
android:id="@+id/imageViewFigure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/animation_speak"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
android:id="@+id/frameLayoutFigure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="60dp"
android:fitsSystemWindows="true"
android:visibility="gone">
<include
layout="@layout/figure"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
package cn.netkiller.student.fragment;
import android.graphics.drawable.AnimationDrawable;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import cn.netkiller.student.R;
public class AnimationFigure {
private static final String TAG = AnimationFigure.class.getSimpleName();
private final View view;
private final ImageView imageViewFigure;
private final FrameLayout frameLayoutFigure;
private final AnimationDrawable animationDrawable;
public AnimationFigure(View view, @DrawableRes int resId) {
this.view = view;
this.imageViewFigure = view.findViewById(R.id.imageViewFigure);
// this.imageViewFigure.setImageResource(resId);
this.imageViewFigure.setBackgroundResource(resId);
this.frameLayoutFigure = view.findViewById(R.id.frameLayoutFigure);
// this.animationDrawable = (AnimationDrawable) this.imageViewFigure.getDrawable();
this.animationDrawable = (AnimationDrawable) this.imageViewFigure.getBackground();
}
public void start() {
animationDrawable.start();
this.frameLayoutFigure.setVisibility(View.VISIBLE);
}
public void stop() {
animationDrawable.stop();
this.frameLayoutFigure.setVisibility(View.INVISIBLE);
}
public void animationFigure() {
AnimationDrawable animationDrawable = (AnimationDrawable) imageViewFigure.getDrawable();
if (animationDrawable.isRunning()) {
animationDrawable.stop();
frameLayoutFigure.setVisibility(View.INVISIBLE);
} else {
animationDrawable.start();
frameLayoutFigure.setVisibility(View.VISIBLE);
}
Log.d(TAG, "animationFigure: " + animationDrawable.isRunning());
Log.d(TAG, "animationFigure isActivated: " + imageViewFigure.isActivated());
}
// public static void animationFigure(View view, AnimationFigure action) {
// ViewSwitcher viewSwitcherFigure = view.findViewById(R.id.viewSwitcherFigure);
// ImageView imageViewFigure = null;
// if (action == AnimationFigure.SPEAKING) {
// viewSwitcherFigure.setDisplayedChild(0);
// imageViewFigure = view.findViewById(R.id.imageViewFigureSpeak);
//// imageViewFigure.setImageResource(R.drawable.animation_loading);
// } else {
// viewSwitcherFigure.setDisplayedChild(1);
//// imageViewFigure.setImageResource(R.drawable.animation_speak);
// imageViewFigure = view.findViewById(R.id.imageViewFigureListening);
// }
// AnimationDrawable animationDrawable = (AnimationDrawable) imageViewFigure.getDrawable();
//
// FrameLayout frameLayoutFigure = view.findViewById(R.id.frameLayoutFigure);
// Log.d(TAG, "animationFigure: " + animationDrawable.isRunning());
// Log.d(TAG, "animationFigure isActivated: " + imageViewFigure.isActivated());
//
// if (animationDrawable.isRunning()) {
// animationDrawable.stop();
// frameLayoutFigure.setVisibility(View.INVISIBLE);
// } else {
// animationDrawable.start();
// frameLayoutFigure.setVisibility(View.VISIBLE);
// }
// Log.d(TAG, "animationFigure: " + animationDrawable.isRunning());
// Log.d(TAG, "animationFigure isActivated: " + imageViewFigure.isActivated());
// }
public enum Figure {
LISTENING, SPEAKING
}
}
<TextClock
android:id="@+id/textClockTime"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:format12Hour="hh:mm"
android:format24Hour="HH:mm"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="40sp"
android:textStyle="bold" />
<TextClock
android:id="@+id/textViewDate"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:format12Hour="yyyy/MM/dd E"
android:format24Hour="yyyy/MM/dd E"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="16sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextClock
android:id="@+id/textClockTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:format24Hour="HH:mm"
android:gravity="center"
android:textColor="@color/white"
android:textSize="48sp" />
<TextClock
android:id="@+id/textViewDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:format12Hour="MM月dd日 EEEE"
android:format24Hour="MM月dd日 EEEE"
android:gravity="center"
android:textColor="#70ffffff"
android:textSize="16sp" />
</LinearLayout>
style属性:
@android:style/Widget.ProgressBar.Horizontal:水平进度条 @android:style/Widget.ProgressBar.Inverse:普通大小的进度条 @android:style/Widget.ProgressBar.Large:大环形进度条 @android:style/Widget.ProgressBar.Large.Inverse:大环形进度条 @android:style/Widget.ProgressBar.Small:小环形进度条 @android:style/Widget.ProgressBar.Small.Inverse:小环形进度条
案例
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="13dp"
android:progress="0"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/textView"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="179dp" />
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="13dp"
android:max="100"
android:maxHeight="32dip"
android:minHeight="32dip"
android:progress="0"
android:progressDrawable="@drawable/progress"
android:progressTint="#43A047"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/textView"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="179dp" />
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置背景色 -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="20dp"></corners>
<solid android:color="#CCCCCC"></solid>
</shape>
</item>
<!-- 设置进度条颜色 -->
<item android:id="@android:id/progress">
<clip>
<shape>
<gradient
android:angle="45"
android:endColor="#2DC8FE"
android:startColor="#149EFF"></gradient>
<!-- 设置圆角 -->
<corners android:radius="20dp"></corners>
</shape>
</clip>
</item>
</layer-list>
<!-- style="@style/Widget.AppCompat.ProgressBar.Horizontal"-->
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="80dp"
android:layout_height="80dp"
android:indeterminate="false"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/circular_progress_drawable"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewTimer" />
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape
android:innerRadiusRatio="3.5"
android:shape="ring"
android:thicknessRatio="12.0"
android:type="sweep"
android:useLevel="false">
<!-- 进度条默认底色 -->
<solid android:color="#f2f2f2" />
</shape>
</item>
<item android:id="@android:id/progress">
<rotate
android:fromDegrees="-90"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-90">
<shape
android:angle="0"
android:innerRadiusRatio="3.5"
android:shape="ring"
android:thicknessRatio="12.0"
android:type="sweep">
<!-- 进度条颜色 -->
<solid android:color="#33cf59" />
</shape>
</rotate>
</item>
</layer-list>
private val handler = Handler(Looper.myLooper()!!)
companion object {
val timerLiveData = MutableLiveData<Pair<Timer, String>>()
}
fun opinionCountDownTimer(seconds: Int) {
val delayMillis: Long = 1000L
var count: Int = seconds
handler.postDelayed(object : Runnable {
override fun run() {
// 百分数 = (1 - 剩余秒数 / 总秒数) × 100
// var percent: Int = (1 - count / seconds) * 100
val percent: Int = ((1 - count.toDouble() / seconds) * 100).toInt()
timerLiveData.postValue(Pair(Timer.OPINION, percent.toString()))
Log.d(TAG, "观点倒计时 ${seconds} ${count} 百分比 ${percent}%")
if (percent < 100) {
count--
handler.postDelayed(this, delayMillis)
}
}
}, delayMillis)
}
Meeting.timerLiveData.observe(this) { (type, time) ->
CoroutineScope(Dispatchers.Main).launch {
if (type == AigcMeeting.Timer.TIMER) {
binding.textViewTimer.text = time
}
if (type == AigcMeeting.Timer.OPINION) {
binding.progressBar.setProgress(time.toInt(), true)
binding.textViewPercent.text = time
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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"
tools:context=".fragment.message.ConsumerAuditFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:text="@string/large_text" />
</androidx.core.widget.NestedScrollView>
package cn.netkiller.student.fragment.message;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import cn.netkiller.student.R;
class ConsumerAuditFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_consumer_audit, container, false);
}
}