Подтвердить что ты не робот

WRAP_CONTENT не работает после динамического добавления просмотров

Я пытаюсь создать фрагмент, который динамически излагает серию пользовательских представлений. Основное содержание этого макета - RelativeLayout, вложенное в LinearLayout (чтобы центрировать его по горизонтали), вложенное в ScrollView.

RelativeLayout имеет несколько TextViews и 9 патчей ImageView, предназначенных для масштабирования с добавлением динамически добавленных пользовательских представлений. Однако изображение (достижения_bgImageView ниже) заканчивается размером экрана и не учитывает размер его родительского RelativeLayout даже после того, как я добавил соответствующее количество пользовательских представлений. Изображение масштабируется отлично, когда я вручную устанавливаю размер достижений_mainLayout (см. Прокомментированные строки ниже), но ничего не делает, если я попытаюсь позволить этому RelativeLayout wrap_content обрабатывать собственный размер.

ScrollView IS, соблюдая размер RelativeLayout, поскольку все содержимое присутствует, это просто изображение, которое не растягивается, чтобы соответствовать содержимому в этой точке.

Любая помощь будет оценена... Мои расчеты вручную не кажутся достаточно хорошими, чтобы учитывать разные устройства, несмотря на то, что я учитываю плотность экрана, и я вручную вынуждаю RelativeLayout к постоянной ширине.

Стоит отметить, что измеренный размер RelativeLayout всегда равен высоте экрана, независимо от того, больше или меньше сумма его содержимого или меньше этой высоты. Поэтому, по сути, WRAP_CONTENT просто не выполняет то, что он должен делать. У меня нет ссылки на любой край RelativeLayout, поэтому круговые зависимости не должны быть проблемой.

fragment_achievements.xml

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true" >

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal">

        <RelativeLayout
                android:layout_width="320dp"
                android:layout_height="wrap_content"
                android:id="@+id/achievements_mainLayout">

            <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:id="@+id/achievements_bgImageView"
                    android:src="@drawable/bkg_achievements9"
                    android:adjustViewBounds="true"
                    android:layout_marginLeft="8dp"
                    android:layout_marginTop="8dp"
                    android:layout_marginRight="8dp"
                    android:layout_centerHorizontal="true"
                    android:scaleType="fitXY"/>

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Name Field"
                    android:id="@+id/achievements_nameTextView"
                    android:layout_alignParentTop="true"
                    android:layout_alignParentLeft="true"
                    android:layout_marginLeft="28dp"
                    android:layout_marginTop="30dp"/>

            <ImageView
                    android:layout_width="52dp"
                    android:layout_height="52dp"
                    android:id="@+id/achievements_avatarImageView"
                    android:layout_below="@+id/achievements_nameTextView"
                    android:layout_alignLeft="@+id/achievements_nameTextView"
                    android:src="@drawable/achieve_avatar"
                    android:layout_marginTop="5dp"/>

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:text="Top Moment:"
                    android:id="@+id/textView2"
                    android:layout_alignBottom="@+id/achievements_avatarImageView"
                    android:layout_toRightOf="@+id/achievements_avatarImageView"
                    android:layout_marginBottom="16dp"
                    android:layout_marginLeft="4dp"
                    android:textSize="12dp"/>

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:text="Me Overall:"
                    android:id="@+id/textView3"
                    android:layout_alignTop="@+id/textView2"
                    android:layout_alignLeft="@+id/textView2"
                    android:layout_marginTop="16dp"
                    android:textSize="12dp"/>

            <TextView
                    android:layout_width="52dp"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:text="153"
                    android:id="@+id/achievements_totalPointsTextView"
                    android:gravity="center"
                    android:layout_alignTop="@+id/achievements_avatarImageView"
                    android:layout_alignRight="@+id/achievements_bgImageView"
                    android:layout_alignEnd="@+id/achievements_bgImageView"
                    android:layout_marginRight="31dp"
                    android:textColor="#f7a033"/>

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Moment"
                    android:id="@+id/achievements_topMomentTextView"
                    android:layout_alignTop="@+id/textView2"
                    android:layout_toRightOf="@+id/textView2"
                    android:layout_marginLeft="5dp"
                    android:textSize="12dp"/>

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="153"
                    android:id="@+id/achievements_overallTextView"
                    android:layout_alignTop="@+id/textView3"
                    android:layout_toRightOf="@+id/textView3"
                    android:layout_marginLeft="5dp"
                    android:textSize="12dp"/>

        </RelativeLayout>
    </LinearLayout>
</ScrollView>

AchievementFragment.java

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View fragmentView = null;

    fragmentView = inflater.inflate(R.layout.fragment_achievements, container, false);

    ImageView avatarImageView = (ImageView)fragmentView.findViewById(R.id.achievements_avatarImageView);

    ...

    // Basic Achievement List Setup
    RelativeLayout mainLayout = (RelativeLayout)fragmentView.findViewById(R.id.achievements_mainLayout);
    AchievementRow currentRow = null;

    List achievementTypeList = CampaignManager.sharedManager().sortedAchievementTypeList();

    int achievementCount = achievementTypeList.size();

    for (int i = 0; i < achievementCount; i++) {
        AchievementType achievementType = (AchievementType)achievementTypeList.get(i);

        // Every third achievement creates a new row.
        if ((i % 3) == 0) {
            AchievementRow row = (AchievementRow)inflater.inflate(R.layout.widget_achievementrow, null);

            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

            if (currentRow == null) {
                layoutParams.addRule(RelativeLayout.BELOW, avatarImageView.getId());
                layoutParams.setMargins(10, 70, 10, 0);
            } else {
                layoutParams.addRule(RelativeLayout.BELOW, currentRow.getId());
                layoutParams.setMargins(10, 10, 10, 0);
            }

            layoutParams.addRule(RelativeLayout.ALIGN_LEFT, backgroundImageView.getId());
            layoutParams.addRule(RelativeLayout.ALIGN_RIGHT, backgroundImageView.getId());

            row.setLayoutParams(layoutParams);
            row.setId(i+1);
            mainLayout.addView(row);

            currentRow = row;
        }

        // Now setup the Button
        AchievementButton achievementButton = currentRow.buttonForIndex(i % 3);
        achievementButton.achievementType = achievementType;
        achievementButton.setOnClickListener(achievementButtonListener);
        achievementButton.setVisibility(View.VISIBLE);

        CacheManager.sharedManager().fetchAchievementThumbnail(getActivity(), achievementButton, achievementType);
    }

    // This is the manual scaling of mainLayout
    // float scale = getResources().getDisplayMetrics().density;
    // float headerHeight = scale * 150.0f;
    // float rowHeight = scale * 78.0f;
    // ViewGroup.LayoutParams mainLayoutParams = mainLayout.getLayoutParams();
    // mainLayoutParams.height = (int)(headerHeight + (Math.ceil(achievementCount / 3.0) * rowHeight));

    return fragmentView;
}
4b9b3361

Ответ 1

Android не обновляет макет представлений с помощью "wrap_content" после его отображения.

Итак, если вы добавите дочерний режим или динамически измените содержимое, вы будете ввернуты. Я согласен с тем, что это кошмар и настоящий недостаток в Android UI!

Чтобы решить эту проблему, я написал статический класс, который пересматривает размеры и заставляет обновить макет для представлений с помощью "wrap_content"

Код и инструкции для использования доступны здесь:

https://github.com/ea167/android-layout-wrap-content-updater

Наслаждайтесь!

Ответ 2

Простой способ обновления размера представления с помощью WRAP_CONTENT изменяет видимость на GONE и обратно на старую видимость.

int visibility = view.getVisibility();
view.setVisibility(View.GONE);
view.setVisibility(visibility);

Ответ 3

Попробуйте вызвать requestLayout для детей.

Недавно у меня была аналогичная проблема, и я был так же расстроен, что вроде invalidate и requestLayout, казалось, ничего не делал. Я не понял, что requestLayout не распространяется на своих детей; распространяется до своих родителей. Чтобы повторно измерить что-то, что было ранее измерено, мне пришлось вызвать requestLayout в представлении, которое изменилось, а не в представлении, которое я действительно хотел изменить.

Ответ 4

Вы получаете эту проблему, потому что сначала устанавливаете свой макет, а затем динамически добавляете его содержимое.

Вы сообщаете макету обернуть содержимое, которое еще не является их. Попробуйте использовать ваш макет надувной воды после того, как вы захватили свой контент

Ответ 5

Хорошо, я решил это, вручную измерив RelativeLayout сразу после добавления всех представлений и установки высоты mainLayoutParams явно. Мне жаль, что я не был умнее и не знал, почему это автоматически не делает это правильно в первую очередь, но хорошо.

    ...
    mainLayout.measure(0, 0);

    ViewGroup.LayoutParams mainLayoutParams = mainLayout.getLayoutParams();
    mainLayoutParams.height = mainLayout.getMeasuredHeight() + 10;
    ...

Ответ 6

Вы должны использовать NestedScrollView вместо простого прокрутки. вот мой пример кода макета деятельности

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F0ECE6"
    >

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />


        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="fixed"
            app:tabIndicatorHeight="6dp"
            android:layout_marginTop="-10dp"
            app:tabGravity="fill"/>
    </android.support.design.widget.AppBarLayout>

    <wsit.rentguru.utility.CustomViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"  />
</android.support.design.widget.CoordinatorLayout>

вот код для настраиваемого viewpager

public class CustomViewPager extends ViewPager {

        private boolean enabled;

        public CustomViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.enabled = false;
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (this.enabled) {
                return super.onTouchEvent(event);
            }

            return false;
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            if (this.enabled) {
                return super.onInterceptTouchEvent(event);
            }

            return false;
        }

        public void setPagingEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }

функция настройки для viewpager в действии

private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new SampleFragment(), " ");

        viewPager.setAdapter(adapter);
    }

class ViewPagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        public void addFragment(Fragment fragment, String title) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }
    }

вот пример кода макета SampleFragment

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#F0ECE6"
    android:fillViewport="true"
    android:scrollbars="vertical"
    android:animateLayoutChanges="true"
    xmlns:android="http://schemas.android.com/apk/res/android">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F0ECE6"
    android:focusableInTouchMode="true"
   >

    <Spinner
        android:id="@+id/product_category"
        android:layout_margin="20dp"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@drawable/edittext_rectangle_box"
        android:gravity="center|left"
        android:textSize="14sp"
        android:paddingLeft="10dp"
        android:drawableRight="@drawable/ic_down_arrow"
        />

    <Spinner
        android:id="@+id/product_sub_category"
        android:layout_below="@+id/product_category"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center|left"
        android:visibility="gone"
        android:paddingLeft="10dp"
        android:background="@android:color/white"
        android:drawableRight="@drawable/ic_down_arrow"
        />
    <EditText
        android:id="@+id/product_title"
        android:layout_below="@+id/product_sub_category"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="15dp"
        android:background="@android:color/white"
        android:hint="PRODUCT TITLE"
        android:singleLine="true"
        android:imeOptions="actionDone"
        android:layout_width="match_parent"
        android:gravity="center|left"
        android:padding="10dp"
        android:textSize="14sp"
        android:textColorHint="#000000"
        android:layout_height="40dp" />

    <LinearLayout
        android:id="@+id/availability_layout"
        android:layout_below="@+id/product_title"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/availability"
            android:textStyle="bold"
            android:paddingBottom="10dp"
            android:textSize="14sp"
            />

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="2">

            <Button
                android:id="@+id/from"
                android:background="@android:color/white"
                android:hint="FROM"
                android:layout_weight="1"
                android:gravity="center|left"
                android:padding="10dp"
                android:textSize="14sp"
                android:textStyle="normal"
                android:textColorHint="#000000"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_marginRight="10dp"/>

            <Button
                android:id="@+id/to"
                android:background="@android:color/white"
                android:hint="TO"
                android:layout_weight="1"
                android:gravity="center|left"
                android:padding="10dp"
                android:textSize="14sp"
                android:textColorHint="#000000"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_marginLeft="10dp"/>



        </LinearLayout>


    </LinearLayout>


    <LinearLayout
        android:id="@+id/product_location_layout"
        android:layout_below="@+id/availability_layout"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/product_location"
            android:textStyle="bold"
            android:paddingBottom="10dp"
            android:textSize="14sp"
            />


        <Spinner
            android:id="@+id/state_spinner"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/edittext_rectangle_box"
            android:gravity="center|left"
            android:textSize="14sp"
            android:layout_marginBottom="10dp"
            android:drawableRight="@drawable/ic_down_arrow"
            android:paddingLeft="10dp"
            />

        <EditText
            android:id="@+id/area"
            android:background="@android:color/white"
            android:hint="Area"
            android:gravity="center|left"
            android:padding="10dp"
            android:textSize="14sp"
            android:textColorHint="#000000"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:singleLine="true"
            android:imeOptions="actionNext"
            android:layout_marginBottom="10dp"
            />


        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="2">

            <EditText
                android:id="@+id/zipCode"
                android:background="@android:color/white"
                android:hint="Zip Code"
                android:layout_weight="1"
                android:gravity="center|left"
                android:padding="10dp"
                android:textSize="14sp"
                android:textColorHint="#000000"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:singleLine="true"
                android:imeOptions="actionNext"
                android:layout_marginRight="10dp"/>

            <EditText
                android:id="@+id/city"
                android:background="@android:color/white"
                android:hint="City"
                android:layout_weight="1"
                android:gravity="center|left"
                android:padding="10dp"
                android:textSize="14sp"
                android:singleLine="true"
                android:imeOptions="actionDone"
                android:textColorHint="#000000"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_marginLeft="10dp"/>



        </LinearLayout>


    </LinearLayout>

    <Button
        android:id="@+id/tab1_next"
        android:layout_width="150dp"
        android:layout_height="40dp"
        android:text="NEXT"
        android:layout_below="@+id/product_location_layout"
        android:layout_margin="20dp"
        android:layout_alignParentRight="true"
        android:background="@color/next_button"
        android:textColor="@android:color/white"
        android:layout_marginBottom="20dp"
        />

</RelativeLayout>

</android.support.v4.widget.NestedScrollView>

Ответ 7

Я думаю, что даже лучший ответ, чем предоставленный до сих пор, заключается в том, что вы должны просто установить ресурс изображения и установить его как полностью прозрачный, когда вы надуваете, а затем, когда вы хотите динамически установить изображение, вы просто сделаете его полностью непрозрачным (или какую опалубу вы хотите).

При инфляции:

ImageView yourImageView = (ImageView) findViewById(R.id.xmlid);
yourImageView.setImageResource(somethingDrawable);
yourImageView.setAlpha(0f);

Позже, когда вы будете готовы динамически установить изображение:

yourImageView.setAlpha(1f);

Ответ 8

Снова установите параметры компоновки (ширина и высота), сразу после добавления представления. Это сработало для меня.

если родительский вид - это FrameLayout, затем выполните примерно так:

    ImageView view = (ImageView) LayoutInflater.from(activity).inflate(R.layout.image_object_view, null);

    imageObjectsHolder.addView(view);
    FrameLayout.LayoutParams param = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    view.setLayoutParams(param);