В моем android приложении есть ViewFlipper, и его дочерние элементы добавляются динамически. На разных эмуляторах все работает нормально, но проблема возникает, когда приложение работает на реальных устройствах.
Проблема в том, что отображается только первый дочерний элемент (изображение или видео), и когда он должен переключаться на следующий, он ничего не показывает, пока другие дочерние элементы отображают время. Когда я печатаю в logcat количество дочерних элементов ViewFlipper или индекс текущего отображаемого дочернего элемента, все правильно, он просто не показывает ни одного из других дочерних элементов.
На данный момент я случайно обнаружил, что все представления отображаются правильно, когда я блокирую, а затем разблокирую экран или когда приложение переходит в фоновый режим, а затем возвращается на передний план. Если вращение происходит после этого исправления, оно снова выходит из строя.
Я специально пытался вызвать onPause () и onResume (), так как он отлично работает при выходе и возвращении на передний план, но это не так. Помогите. Кроме того, я попытался с помощью этого ViewFlipper показать макет в виде диалогового окна, сделать его продолжительностью до первого дочернего элемента плюс одна секунда, чтобы он мог перейти ко второму, а затем уничтожить его, но оказалось что это не срабатывало каждый раз.
Поскольку я не смог программно исправить такое поведение, я надеюсь, что кто-нибудь сможет мне с этим помочь.
Вот код, относящийся к этой части приложения.
Функция, вызываемая из onInit (), используемая для установки дочерних элементов ViewFlipper:
public static void setMedia(final WeakReference<MainActivity> activityWeakReference) {
flipperObjects.clear(); // flipperObject is an ArrayList of Media objects (contain information about the url and duration od image or video)
((ViewFlipper) activityWeakReference.get().findViewById(R.id.media)).removeAllViews();
for (final Media m : currentMedia.getMedia()) {
if (m.getLocalUrl() != null && !m.getLocalUrl().equals("null")) { // Images and videos are previously downloaded on device
if (m.getLocalUrl().matches(".*\\.(?:jpg|jpeg|png)")) {
final ImageView imageView = new ImageView(activityWeakReference.get());
File imgFile = new File(m.getLocalUrl());
imageView.setImageBitmap(BitmapFactory.decodeFile(imgFile.getAbsolutePath()));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
boolean shouldAdd = true;
for (ReklamaStavka r : flipperObjects) {
if (r.getLocalUrl().equals(m.getLocalUrl())) {
shouldAdd = false;
break;
}
}
if (shouldAdd) {
flipperObjects.add(m);
((ViewFlipper) activityWeakReference.get().findViewById(R.id.media)).addView(imageView);
}
} else {
final ScaledVideoView videoView = new ScaledVideoView(activityWeakReference.get());
videoView.setVideoURI(Uri.fromFile(new File(m.getLocalUrl())));
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
}
});
MediaController mediaController = new MediaController(activityWeakReference.get());
mediaController.setVisibility(View.GONE);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.reset();
}
});
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e("ERROR", "Video isn't played");
return true;
}
});
boolean shouldAdd = true;
for (Media m1 : flipperObjects) {
if (m1.equals(m)) {
shouldAdd = false;
break;
}
}
if (shouldAdd) {
flipperObjects.add(m);
((ViewFlipper) activityWeakReference.get().findViewById(R.id.media)).addView(videoView);
}
}
}
}
currentIndex = 0;
endIndex = ((ViewFlipper) activityWeakReference.get().findViewById(R.id.media)).getChildCount();
}
Функция, вызываемая после предыдущей, используемая для выполнения переворачивание через определенное количество секунд:
private static void nextChild(final WeakReference<MainActivity> activityWeakReference) {
int delaySeconds = 0;
if (flipperObjects.size() > 0) {
((ViewFlipper) activityWeakReference.get().findViewById(R.id.media)).setDisplayedChild(currentIndex);
delaySeconds = flipperObjects.get(currentIndex).getDuration();
currentIndex++;
if (currentIndex >= endIndex) {
currentIndex = 0;
}
}
if (nextImageHandler == null) {
nextImageHandler = new Handler(Looper.getMainLooper());
}
nextImageHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (running) {
nextChild(activityWeakReference);
}
}
}, delaySeconds * 1000);
}
Вот моя функция onDestroy ():
@Override
protected void onDestroy() {
running = false;
flipperObjects.clear();
((ViewFlipper) findViewById(R.id.media)).removeAllViews();
currentIndex = 0;
endIndex = 0;
if (nextImageHandler != null) {
nextImageHandler.removeCallbacksAndMessages(null);
}
super.onDestroy();
}
А вот activity_main. xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="1" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="1" />
<ViewFlipper
android:id="@+id/media"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@string/app_name"
app:layout_constraintBottom_toTopOf="@+id/guidelineBottom"
app:layout_constraintEnd_toStartOf="@+id/guidelineRight"
app:layout_constraintStart_toStartOf="@+id/guidelineLeft"
app:layout_constraintTop_toTopOf="@+id/guidelineTop"
tools:srcCompat="@tools:sample/backgrounds/scenic" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header"
app:itemBackground="@android:color/transparent"
app:menu="@menu/drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>