Reputation: 380
I've been working on an app that uses a vertical RecyclerView inside a fragment, all inside a ViewPager2 object with a tabLayout. I can't seem to figure out how to make all these things work together. Currently, it looks like I got it to show the recycler view with the data but the tabs aren't showing up and the items in the list are spaced like they're different pages. Could someone explain how I'm messing up?
It looks like this:
I'd like it to be like this:
Here's the code so far:
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();
}
}
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;
}
}
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");
}
}
}
<?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>
<?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>
<?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>
Upvotes: 2
Views: 4906
Reputation: 2312
In your list_view , Use your parent layout height wrap_content not 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>
Upvotes: 0
Reputation: 1986
for tablayout :
take/make tablayout outside the CollapsingToolbarLayout
and for "list are spaced" :
make wrap_content
height in view_page code
also list_view LinearLayout height to wrap_content
hope it helped :)
Upvotes: 4