带有 RecyclerView 的 ViewPager2 显示不正确

ViewPager2 with RecyclerView not displaying correctly

我一直在开发一个在片段内使用垂直 RecyclerView 的应用程序,所有内容都在带有 tabLayout 的 ViewPager2 对象内。我似乎无法弄清楚如何让所有这些东西一起工作。目前,看起来我得到它来显示带有数据的回收站视图,但选项卡没有显示,列表中的项目间隔开,就像它们是不同的页面一样。谁能解释一下我是怎么搞砸的?

看起来像这样:

我希望它是这样的:

目前的代码如下:

MainActivity.java

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.Style;

public class MainActivity extends AppCompatActivity {

    private MapView mapView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Mapbox Access token
        Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_api_key));

        setContentView(R.layout.activity_main);

        mapView = findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(Style.DARK, style -> {

            // Map is set up and the style has loaded. Now you can add data or make other map adjustments


        }));

        ViewPager2 pager = findViewById(R.id.view_pager);

        ViewPageAdapter pageAdapter = new ViewPageAdapter(getSupportFragmentManager(), getLifecycle());
        pager.setAdapter(pageAdapter);

        pager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);

        TabLayout tabLayout = findViewById(R.id.tabLayout2);
        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
        new TabLayoutMediator(tabLayout, pager,
                (tab, position) -> {
                    switch (position) {
                        case 0:
                            tab.setText(getString(R.string.stats_tab));
                            break;
                        case 1:
                            tab.setText(getString(R.string.news_tab));
                            break;
                        case 2:
                            tab.setText(getString(R.string.symptoms_tab));
                            break;
                        case 3:
                            tab.setText(getString(R.string.safety_tab));
                            break;
                        default:
                            break;
                    }
                }).attach();

        // Get data
        new StatsLoader("https://api.covid19api.com/summary", pageAdapter, pager).execute();

    }
}

StatsFragment.java

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;

public class StatsFragment extends Fragment {

    View view;
    RecyclerView recyclerView;
    JSONArray covidData;

    public StatsFragment(JSONArray data) {
        covidData = data;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.view_page, container, false);
        recyclerView = view.findViewById(R.id.recyclerView2);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(false);
        RecyclerView.Adapter<CustomListAdapter.ListViewHolder> mAdapter = new CustomListAdapter(covidData);
        recyclerView.setAdapter(mAdapter);
        return view;
    }
}

StatsLoader.java

import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.Nullable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.net.ssl.HttpsURLConnection;

public class StatsLoader extends AsyncTask<String, Void, JSONArray> {

    Exception exception;
    String urlString = "";
    static JSONArray covidData = new JSONArray();
    ViewPageAdapter pageAdapter;

    public StatsLoader(String url, ViewPageAdapter adapter) {
        super();
        urlString = url;
        pageAdapter = adapter;
    }

    @Nullable
    @Override
    public JSONArray doInBackground(String ... urls) {
        HttpsURLConnection connection = null;
        BufferedReader reader = null;

        try {

            URL url = new URL(urlString);
            connection = (HttpsURLConnection) url.openConnection();
            connection.connect();
            InputStream inputStream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream));

            StringBuilder buffer = new StringBuilder();
            String line = "";

            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

            JSONObject json = new JSONObject(buffer.toString());
            covidData = json.getJSONArray("Countries");
            ArrayList<Object> list = new ArrayList<>();
            for (int i = 0; i < covidData.length(); i++) {
                list.add(covidData.get(i));
            }
            SortJsonArray sortJsonArray = new SortJsonArray();
            sortJsonArray.sortArray(list, "TotalConfirmed", false);
            covidData = new JSONArray();
            for (Object object : list) {
                covidData.put(object);
            }
            return covidData;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    protected void onPostExecute(JSONArray coviddata) {

        if (this.exception == null) {
            Log.d("Check", "Works!");
            pageAdapter.addFragment(new StatsFragment(coviddata), "Stats");
        }

    }


}

布局

activity_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:statusBarScrim="@null"
            app:titleEnabled="false"
            android:minHeight="?attr/actionBarSize" >

            <fragment
                android:id="@+id/mapView"
                android:name="com.mapbox.mapboxsdk.maps.MapFragment"
                android:layout_width="match_parent"
                android:layout_height="350sp"
                android:apiKey="@string/mapbox_api_key"
                android:clickable="true"
                android:enabled="true"
                android:focusable="true"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/appbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_marginBottom="48dp"
                android:gravity="top"
                app:layout_collapseMode="pin"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
                app:title="" />

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="parent">

            </com.google.android.material.tabs.TabLayout>


        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="parent"
            tools:listitem="@layout/view_page" >

        </androidx.viewpager2.widget.ViewPager2>


    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

view_page

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="parent"
        tools:listitem="@layout/list_view">

    </androidx.recyclerview.widget.RecyclerView>

</androidx.constraintlayout.widget.ConstraintLayout>

list_view

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.cardview.widget.CardView
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="14sp"
        android:layout_margin="15sp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="40sp">

            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toLeftOf="@+id/name"
                android:layout_toStartOf="@+id/name"
                android:contentDescription="Image of country flag" />

            <TextView
                android:id="@+id/name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="10sp" />

            <TextView
                android:id="@+id/cases"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/name" />

        </RelativeLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

用于 tablayout :

take/make tablayout 在 CollapsingToolbarLayout

之外

并且对于“列表是间隔的” :

在view_page代码中制作wrap_content高度

也list_view LinearLayout 高度到wrap_content

希望对您有所帮助:)

在您的 list_view 中,使用您的父布局高度 wrap_content 而不是 match_parent

<androidx.cardview.widget.CardView
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="14sp"
    android:layout_margin="15sp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="40sp">

        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/name"
            android:layout_toStartOf="@+id/name"
            android:contentDescription="Image of country flag" />

        <TextView
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="10sp" />

        <TextView
            android:id="@+id/cases"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/name" />

    </RelativeLayout>

</androidx.cardview.widget.CardView>