ViewFlipper не показывает всех своих дочерних элементов - PullRequest
0 голосов
/ 13 июля 2020

В моем 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>
...