SupportMapFragment с настраиваемым видом сверху

У меня есть некоторые проблемы с настройкой макета SupportMapFragment. Я в основном хочу добавить пользовательский вид в нижней части макета фрагмента карты.

Мне удалось добавить представление программно к фрагменту так:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View mapView = super.onCreateView(inflater, container, savedInstanceState);
    View customView = inflater.inflate(R.layout.custom_view, container, false);

    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) customView.getLayoutParams();
    params.gravity = Gravity.BOTTOM;
    customView.setLayoutParams(params);

    FrameLayout wrapper = new FrameLayout(inflater.getContext());
    wrapper.addView(mapView);
    wrapper.addView(customView);

    return wrapper;
}

Макет custom_view представляет собой простой CardView без сложной логики:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
        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/custom_view_root"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:visibility="gone"
        app:cardBackgroundColor="@color/white"
        >

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

            ... some basic content

    </LinearLayout>


</android.support.v7.widget.CardView>

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

LE: Как упомянул @Budius в своем ответе, я пропустил корневой параметр ViewGorup метода inflate ().

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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    FrameLayout wrapper = new FrameLayout(inflater.getContext());

    View mapView = super.onCreateView(inflater, container, savedInstanceState);
    wrapper.addView(mapView);

    customView = inflater.inflate(R.layout.custom_view, wrapper, false);
    wrapper.addView(customView);

    return wrapper;
}

Другое решение для этого состоит в том, чтобы создать параметры пользовательского представления программно, как это:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View mapView = super.onCreateView(inflater, container, savedInstanceState);
    customView = inflater.inflate(R.layout.custom_view, container, false);
    FrameLayout wrapper = new FrameLayout(inflater.getContext());
    wrapper.addView(mapView);

    FrameLayout.LayoutParams params =
            new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT,
                                         Gravity.BOTTOM);
    wrapper.addView(customView, params);

    return wrapper;
}

1 ответ

Решение

Строка кода inflater.inflate(R.layout.custom_view, container, false); container он предназначен для указания LayoutParams, который будет использоваться из XML в родительский макет. Но затем вы создали экземпляр LinearLayout.LayoutParams. А потом вы добавили его в FrameLayout. Так что все это было отброшено, потому что оно не совпадает.

Есть несколько простых способов исправить это:

Вы можете надуть CardView с помощью правильного родительского макета:

// add this line AFTER you created the FrameLayout
View customView = inflater.inflate(R.layout.custom_view, wrapper, false);

Вы можете надуть CardView прямо внутри wrapper просто изменив на true,

// this will correctly use the layout params you set on XML and add the inflated views into wrapper
inflater.inflate(R.layout.custom_view, wrapper, true);

Вы можете создать свои параметры как правильный тип:

// use FrameLayout.LayoutParams when using FrameLayout as the parent.
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) customView.getLayoutParams();
params.gravity = Gravity.BOTTOM;
customView.setLayoutParams(params);
Другие вопросы по тегам