Создание макета CardView - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь создать макет CardView, который будет повторно использоваться для отображения твита на странице профиля и в RecyclerView на домашней странице.Разница в том, что RecyclerView будет раздувать сам макет, а на странице профиля будет использоваться настраиваемое представление.

Однако при использовании настраиваемого представления на странице профиля создается дополнительное CardView за ним.Мое лучшее предположение состоит в том, что это происходит потому, что пользовательское представление расширяется от класса CardView и, конечно, RecyclerView не расширяет этот класс.

Итак, в итоге я получаю CardView с моиммакет внутри него, как показано на изображении ниже: макет в CardView

В то время как в RecyclerView он выглядит так, как должен: макет раздут в RecyclerView

Я также попытался расширить класс пользовательского представления с помощью LinearLayout и FrameLayout вместо CardView, но с CardView все еще в качестве корня в tweet.xml.Это частично избавило от проблемы, но даже с setClipToPadding(false) и setClipChilderen(false) оно все равно обрезало бы часть теневой границы CardView.

Я пытался выйти из CardView, покакорень в tweet.xml должен быть LinearLayout или FrameLayout и выполнять стилизацию внутри Java. Но это привело к еще одному «недостатку» при использовании значения радиуса карты с setRadius(R.dimen.card_corner_radius) (равным 8dp).И я получил this .

Так как мне сохранить CardView в качестве корня в моем файле xml при использовании его в качестве пользовательского представления?

tweet.xml Предварительный просмотр

<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:elevation="2dp"
    app:cardCornerRadius="@dimen/card_corner_radius"
    app:contentPaddingBottom="8dp"
    android:foreground="?attr/selectableItemBackground"
    android:layout_marginStart="@dimen/card_spacing_horizontal"
    android:layout_marginEnd="@dimen/card_spacing_horizontal"
    android:layout_marginTop="@dimen/card_spacing_vertical"
    android:clickable="true"
    android:focusable="true"
    style="@style/CardView">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="128dp"
            android:scaleType="centerCrop"
            android:src="@drawable/ic_default_image"
            android:foreground="?attr/selectableItemBackground"
            android:visibility="visible" />

        <!-- Rest of layout -->

    </android.support.constraint.ConstraintLayout>

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

TweetView.java

public class TweetView extends CardView {

    public TweetView(Context context) {
        this(context, null /* attrs */);
    }

    public TweetView(Context context, AttributeSet attrs) {
        this(context, attrs, R.style.AppTheme);
    }

    public TweetView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.tweet, this);
    }
}

fragment_profile.xml Предварительный просмотр

<?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="match_parent"
    tools:context=".fragments.ProfileFragment">

    <nl.robinpfeiffer.parrot.twitter.views.TweetView
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"/>

</LinearLayout>

EDIT

Я попытался изменить код TweetView.java, как предложено @Eminem.Но CardView остается прежним;вложенный в другой CardView.

TweetView.java Обновлено

LayoutInflater mInflater;

public TweetView(Context context) {
    super(context);
    mInflater = LayoutInflater.from(context);
    init();
}

public TweetView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mInflater = LayoutInflater.from(context);
    init();
}

public TweetView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mInflater = LayoutInflater.from(context);
    init();
}

private void init() {
    View v = mInflater.inflate(R.layout.tweet, this, true);
}

РЕДАКТИРОВАТЬ 2:

Я не обратил особого внимания, когда не удалось стиль Java, и забылчто это должно было быть setRadius(getResources().getDimension(R.dimen.card_corner_radius)); вместо setRadius(R.dimen.card_corner_radius);, поскольку последний использует значение целочисленного идентификатора ресурса для радиуса.Отсюда способ слишком закругленных углов.

1 Ответ

0 голосов
/ 18 мая 2018

Итак, я, наконец, исправил, как предложил @Eminem, тег <merge>. Поскольку я расширяю свой класс TweetView с CardView, он автоматически создает CardView. В TweetView макет tweet.xml get раздувается с помощью inflate(getContext, R.layout.tweet, this) Стили теперь обрабатываются в файлах styles.xml путем создания собственного стиля карты. Этот стиль должен применяться там, где вы используете класс TweetView.

Мои полученные файлы макетов и классов выглядят следующим образом:

tweet.xml

    <?xml version="1.0" encoding="utf-8"?>
<merge 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"
    tools:parentTag="android.support.v7.widget.CardView">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:foreground="?attr/selectableItemBackground"
        android:paddingBottom="8dp"
        android:focusable="true">

        <!-- Rest of internal layout -->

    </android.support.constraint.ConstraintLayout>

</merge>

TweetView.java

public class TweetView extends CardView implements Observer {

public TweetView(Context context) {
    super(context);
    init();
}

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

public TweetView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    inflate(getContext(), R.layout.tweet, this);
}

styles.xml

   <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="android:navigationBarColor">@color/colorPrimaryDark</item>
        <!-- Base theme items -->
    </style>

    <style name="CardTweet" parent="CardView">
        <!-- Custom card items -->
        <item name="cardCornerRadius">@dimen/card_corner_radius</item>
    </style>

И, наконец, вот как я использовал класс в стандартном Fragment и RecyclerView:

fragment_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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="match_parent"
    tools:context=".fragments.ProfileFragment">

        <nl.robinpfeiffer.parrot.twitter.views.TweetView
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            style="@style/CardTweet"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

fragment_tweet.xml это RecyclerView предмет, который раздувается в RecyclerViewAdapter

<?xml version="1.0" encoding="utf-8"?>
<nl.robinpfeiffer.parrot.twitter.views.TweetView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/CardTweet"
    android:layout_marginEnd="@dimen/card_spacing_horizontal"
    android:layout_marginStart="@dimen/card_spacing_horizontal"
    android:layout_marginTop="@dimen/card_spacing_vertical" />

Фиксированная карта, нормальная раскладка

Фиксированная карта, RecyclerView

...