how to make wrap_content property works in viewPager(which in a dialogFragment)

24 Views Asked by At

i create a dialogFragment to show a dialog for user, and i try to use a viewPager in this dialog. Without this viewPager, i can make this dialog's height wrap the content. but after using viewpager, the dialog height is full fill the window, what i need is to make the viewPager height to wrap_content.

here's my XML file for the dialogFramgnet & viewPager's items

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/round_backgroud"
    android:orientation="vertical">

    <com.tomastu.lottiedemo.AutoViewPage
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="24dp"
        android:layout_marginBottom="24dp"
        android:background="@color/black"
        android:text="确认"
        android:textAlignment="center"
        android:textColor="@color/white" />

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/view_pager_child_1"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/hint_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="STEP 1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/hint_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:text="抬起手机"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/hint_title" />

    <ImageView
        android:id="@+id/guide_video"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginTop="40dp"
        android:background="@color/black"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/hint_content" />
</androidx.constraintlayout.widget.ConstraintLayout>

i tried to extend the ViewPager class and implement a custom ViewPager to override the onMeasure method, but it failed. here's what i have tried.

package com.tomastu.lottiedemo;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import androidx.viewpager.widget.ViewPager;

public class AutoViewPage extends ViewPager {
    public AutoViewPage(Context context) {
        super(context);
    }

    public AutoViewPage(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            ViewGroup.LayoutParams params = child.getLayoutParams();
            int childWidthMeaSpec = getChildMeasureSpec(widthMeasureSpec,
                    getPaddingLeft() + getPaddingRight(), params.width);
            int childHeightMeaSpec = getChildMeasureSpec(heightMeasureSpec,
                    getPaddingTop() + getPaddingBottom(), params.height);
            child.measure(childWidthMeaSpec, childHeightMeaSpec);
            int h = child.getMeasuredHeight();
            if (h > height) height = h;
        }
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

and i also custom the width for the dialogFragment, here's the code

package com.tomastu.lottiedemo;

import android.app.Dialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class myDialogFragment extends DialogFragment {
    private final List<View> mViews = new ArrayList<>();
    private PagerAdapter mAdapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View inflate = inflater.inflate(R.layout.my_dialog_fragment, container);
        Dialog d = requireDialog();
        d.setCanceledOnTouchOutside(false);

        mViews.add(inflater.inflate(R.layout.view_pager_child_1, d.findViewById(R.id.view_pager), false));
        mViews.add(inflater.inflate(R.layout.view_pager_child_2, d.findViewById(R.id.view_pager), false));

        mAdapter = new PagerAdapter() {
            @Override
            public int getCount() {
                return mViews.size();
            }

            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                return view == object;
            }

            @Override
            public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
                container.removeView(mViews.get(position));
            }

            @NonNull
            @Override
            public Object instantiateItem(@NonNull ViewGroup container, int position) {
                View item = mViews.get(position);
                container.addView(item);
                return item;
            }
        };

        return inflate;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ViewPager viewPager = view.findViewById(R.id.view_pager);
        viewPager.setAdapter(mAdapter);
    }

    @Override
    public void onStart() {
        super.onStart();

        Window w = Objects.requireNonNull(getDialog()).getWindow();
        if (w == null) {
            return;
        }

        float scale = this.getResources().getDisplayMetrics().density;
        int width = this.getResources().getDisplayMetrics().widthPixels;
        int width4Dialog = (int) (368 * scale + 0.5f);
        if ((width / scale + 0.5f) <= 392)
            width4Dialog = (int) (width - (24 * scale + 0.5f));

        w.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        WindowManager.LayoutParams attributes = w.getAttributes();
        attributes.width = width4Dialog;
        w.setAttributes(attributes);
    }
}
1

There are 1 best solutions below

0
tomastu On

I changed override onCreateView to onCreateDialog and it works. Maybe someone know why, but that is my solution :-)