First let me clarify that i have found a few questions similar to this question, but none worked for me.
So i have one activity (MainActivity.java), which has a bottom navigation tab, each tab has its own fragment, the third fragment is named 'ServiceFragment.java' (also the third tab in Bottom navigation).
Classes:
ServiceFragment.java
package in.ikleen.ikleenservices;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ServiceFragment extends Fragment {
Context context;
public ServiceFragment() {
// Required empty public constructor
}
#Override
public void onAttach (Context context){
super.onAttach(context);
this.context = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_service, container, false);
ViewPager viewPager = rootView.findViewById(R.id.service_view_pager);
viewPager.setOffscreenPageLimit(3);
TabLayout tabLayout = rootView.findViewById(R.id.service_tab_layout);
ServiceFragmentPageAdapter pageAdapter = new ServiceFragmentPageAdapter(context, getChildFragmentManager());
viewPager.setAdapter(pageAdapter);
tabLayout.setupWithViewPager(viewPager);
return rootView;
}
}
ServiceFragmentPageAdapter.java
package in.ikleen.ikleenservices;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class ServiceFragmentPageAdapter extends FragmentPagerAdapter {
private Context mContext;
Fragment zero, first, second;
public ServiceFragmentPageAdapter (Context context, FragmentManager fm){
super(fm);
mContext = context;
zero = new WashDryServiceFragment();
first = new WashDryIronServiceFragment();
second = new AdditionalProductsServiceFragment();
}
#Override
public Fragment getItem(int position){
switch (position){
case 0:
return zero;
case 1:
return first;
case 2:
return second;
default:
return zero;
}
}
#Override
public int getCount(){
return 3;
}
#Override
public CharSequence getPageTitle(int position){
switch (position){
case 0:
return mContext.getString(R.string.wash_dry);
case 1:
return mContext.getString(R.string.wash_dry_iron);
case 2:
return mContext.getString(R.string.additional_products);
default:
return mContext.getString(R.string.wash_dry);
}
}
}
WashDryServiceFragment.java (the first tab of viewpager tablayout, also the one bearing the problem)
package in.ikleen.ikleenservices;
import android.annotation.TargetApi;
import android.os.Bundle;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.app.Fragment;
import android.support.v4.widget.NestedScrollView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toolbar;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
public class WashDryServiceFragment extends Fragment {
public WashDryServiceFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_wash_dry_service, container, false);
ListView listView = (ListView) rootView.findViewById(R.id.listViewWashDryService);
ArrayList<String> stringList = new ArrayList<>();
for(int i=0; i<20; i++) {
stringList.add("Hello");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, stringList);
listView.setAdapter(adapter);
//TESTED BELOW CODE BUT CANNOT EVEN SCROLL A LITTLE BIT SO COMMENTED IT
//Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar1);
//NestedScrollView nestedScrollView = (NestedScrollView) rootView.findViewById(R.id.nestedScroll);
//CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) nestedScrollView.getLayoutParams();
//params.setBehavior(new ConstrainedScrollBehavior());
return rootView;
}
}
Layouts:
fragment_service.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="in.ikleen.ikleenservices.ServiceFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/service_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextAppearance="#style/Base.TextAppearance.AppCompat.Small"
app:tabMode="fixed"/>
<android.support.v4.view.ViewPager
android:id="#+id/service_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</FrameLayout>
fragment_wash_dry_service.xml (THE PROBLEM LIES HERE)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="in.ikleen.ikleenservices.WashDryServiceFragment">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="150dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
app:layout_collapseMode="parallax"
android:scaleType="centerInside"
app:layout_collapseParallaxMultiplier="0.5"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:src="#mipmap/ld_00"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScroll"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_gravity="fill_vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:orientation="vertical">
<ListView
android:id="#+id/listViewWashDryService"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appBarLayout"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="JUST FOR TESTS"
android:textAppearance="#style/TextAppearance.AppCompat.Large"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
</FrameLayout>
Thanks
The problem in this case was: (p.s. i am stupid)
listview cannot scroll inside nestedscrollview, so as soon as the collapsingtoolbar collapsed, there was no need for the nestedscrollview to scroll more as it already filled the parent and listview could not scroll anyways. (i know, dumb explanation)
Solution:
1: either remove listview inside the nestedscrollview
OR
2: add this attribute android:nestedScrollingEnabled="true" inside nestedscrollview (not tested, but should work)
Related
I am now learning to create tabbed activities and I've choosen PagerTabStrip to work with. But now when I'm created fragments, assigned them po Adapter, and assigned adapter to ViewPager, Tab navigation panel of PagerTabStrip is missing
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.player.pagertabstrip.MainActivity"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/viewPager">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
</LinearLayout>
PageFragment.java
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class PageFragment extends Fragment {
private static final String ARG_PAGE_NUMBER = "page_number";
public PageFragment() {
}
public static PageFragment newInstance(int page) {
PageFragment fragment = new PageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE_NUMBER, page);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_page_layout, container, false);
TextView txt = (TextView) rootView.findViewById(R.id.page_number_label);
int page = getArguments().getInt(ARG_PAGE_NUMBER, -1);
txt.setText(String.format("Page %d", page));
return rootView;
}
}
fragment_page_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.player.pagertabstrip.PageFragment">
<TextView android:id="#+id/page_number_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#android:style/TextAppearance.Large"
android:gravity="center"
android:layout_centerVertical="true" />
</RelativeLayout>
MainActivity.java
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabsPagerAdapter tabsPagerAdapter = new TabsPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = (ViewPager)findViewById(R.id.viewPager);
viewPager.setAdapter(tabsPagerAdapter);
}
}
and screenshot of No tab navigation:-
So, it seems to be bug in com.android.support:appcompat-v7:24.0.0 library.
I found 2 ways to solve this problem.
First:
You must downgrade your library which used in your project. In your gradle file replace compile 'com.android.support:appcompat-v7:24.0.0' to compile 'com.android.support:appcompat-v7:23.2.0'
Second:
You can change property of child PagerTabStrip by accessing via it's parent's LayoutParams
((ViewPager.LayoutParams) pagerTabStrip.getLayoutParams()).isDecor = true;
I want to create an Activity with tabs (probably using TabHost) that looks something like this:
This layout also has some buttons, checkboxes and a gridview, but I'm mostly interested to find out how I would have my tabs look like this, because by default they look something like this:
My problem is that I have no clue how to do it, I have made drawables for some UI components before, but this is something different, I think.
After quite some time I have figured how to get what I wanted, by trying out a lot of different ways to make tabs an I finally ended up using a TabLayout with a ViewPager.
I have made a Proof of Concept and it looks like this:
If anyone is interested in the code, this is the layout of the main activity
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="10">
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.2"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabPaddingStart="2dp"
app:tabPaddingEnd="2dp"
app:tabPaddingTop="2dp"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5.8"/>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
The MainActivity.java:
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements FirstTabFragment.OnFragmentInteractionListener, SecondTabFragment.OnFragmentInteractionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT);
viewPager.setAdapter(new SectionPagerAdapter(getSupportFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
TabLayout.Tab tab = tabLayout.getTabAt(0);
RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.tab_layout_file1, tabLayout, false);
TextView tabTextView = (TextView) relativeLayout.findViewById(R.id.tab_title);
tabTextView.setText(tab.getText());
tab.setCustomView(relativeLayout);
TabLayout.Tab tab2 = tabLayout.getTabAt(1);
RelativeLayout relativeLayout2 = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.tab_layout_file2, tabLayout, false);
TextView tabTextView2 = (TextView) relativeLayout2.findViewById(R.id.tab_title);
tabTextView2.setText(tab2.getText());
tab2.setCustomView(relativeLayout2);
tab.select();
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class SectionPagerAdapter extends FragmentPagerAdapter {
public SectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FirstTabFragment();
case 1:
default:
return new SecondTabFragment();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "First Tab";
case 1:
default:
return "Second Tab";
}
}
}
}
TabLayout1 (TabLayout2 is the same but uses shape2)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tab_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#drawable/shape1"
android:textColor="#android:color/white"/>
</RelativeLayout>
The shapes are just a red and a blue rectangle and and the Fragments are default
empty Fragments with the same color background as the shapes.
I have a recipe fragment that has a header image and a ViewPager, and I'm facing two problems with the current design:
1- The tabs content are not scrolling vertically unless I press on the header image and start scrolling. What I mean by this is that if I swipe vertically on the header image the view will scroll. BUT if I try to swipe vertically from the text area it doesn't scroll. (I have an image below)
2- The header image is not all the way up to replace the toolbar like the current version Google Play Store displays apps like the the first screenshot below, and the second screenshot is how my app looks like.
Here is my my fragment_recipe.xml:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/tab_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/tab_collapse_toolbar"
android:layout_width="match_parent"
android:layout_marginTop="25dp"
android:layout_height="256dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/recipe_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/header"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
/>
<android.widget.Toolbar
android:id="#+id/tab_toolbar"
android:layout_width="match_parent"
android:layout_height="104dp"
android:gravity="top"
android:minHeight="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:titleMarginTop="13dp" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:layout_scrollFlags="scroll|enterAlways"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:tabIndicatorColor="#android:color/white" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
And here is my FargmentRecipe.java:
import android.annotation.TargetApi;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import java.util.ArrayList;
import java.util.List;
import mamoonbraiga.MealMate.activities.MainActivity;
import mamoonbraiga.MealMate.extras.Recipe;
import mamoonbraiga.MealMate.network.VolleySingleton;
import mamoonbraiga.poodle_v3.R;
public class FragmentRecipe extends Fragment{
private ImageView header;
private VolleySingleton volleySingleton = VolleySingleton.getsInstance();;
private ImageLoader imageLoader=volleySingleton.getImageLoader();;
private Bundle bundle;
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
final View view = inflater.inflate(R.layout.fragment_recipe, container, false);
MainActivity mainActivity = (MainActivity) getActivity();
header = (ImageView) view.findViewById(R.id.recipe_header); //setting up the header
bundle = mainActivity.getSavedData();
Recipe recipe = bundle.getParcelable("recipe");
//load the header
loadHeader(recipe);
((MainActivity) getActivity()).getSupportActionBar().hide();
Toolbar toolbar = (Toolbar) view.findViewById(R.id.tab_toolbar);
mainActivity.setActionBar(toolbar);
mainActivity.getActionBar().setDisplayHomeAsUpEnabled(true);
/** view pager and tab setup **/
final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setVerticalScrollBarEnabled(true);
setUpViewPager(viewPager);
final TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FF5722"));
tabLayout.setupWithViewPager(viewPager);
/** view pager and tab setup **/
return view;
}
private void loadHeader(Recipe recipe) {
imageLoader.get(recipe.getImageUrl(), new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
Drawable d = new BitmapDrawable(getResources(), response.getBitmap());
header.setBackground(d);
}
#Override
public void onErrorResponse(VolleyError error) {
}
});
}
private void showToast(String msg) {
Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
}
private void setUpViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
adapter.addFrag(new FragmentDescription(), "Description");
adapter.addFrag(new FragmentIngredients(), "Ingredients");
adapter.addFrag(new FragmentNutrition(), "Nutrition");
viewPager.setAdapter(adapter);
}
static class ViewPagerAdapter extends FragmentStatePagerAdapter{
private final List<String> mFragmentTitleList = new ArrayList<>();
private final List<Fragment> mFragmentList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position){
return mFragmentTitleList.get(position);
}
}
#Override
public void onPause(){
super.onPause();
((MainActivity) getActivity()).getSupportActionBar().show();
}
}
1) I don't have your fragments layouts xml (FragmentDescription, FragmentIngredients and FragmentNutrition layouts) but I am guessing your are using ScrollView instead of NestedScrollView. Try this at the root of your nested fragments:<android.support.v4.widget.NestedScrollView>
2) When your header collapse, do you still have the black status bar? If so, you have to add transparency to your status bar.So in your theme: <item name="android:statusBarColor">#80000000</item>
(here I am using a dark transparent color, to make it look nicer, but it's up to you)
Note also that you cannot get full transparent status bar on pre-Lollipop devices.
2bis) if you already have a transparent statusbar (you see the image passing behind after a bit of scrolling up), then you can try this hack:
<ImageView
android:id="#+id/recipe_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/header"
android:layout_marginTop="-24dp"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
/>
This will move the image up by the height of the status bar, thus making it fit with the top of the window. There is probably a proper solution, but it is the one I am using at the moment.
I have looked at a few similar incidents of this on StackOverflow. However none seem to apply to my case. The issue I'm having is that my RecyclerView is working but nothing is displaying. I have run multiple tests to try and figure out why it isn't working but all have just supported the fact that it is working correctly.
The log in getItemCount returns 3, which is the correct number. I just don't understand why it is not showing. I looked back at a recycler view I did in a previous activity and they both match to an extent(Other recycler has more information to set).
Thank you for any help you can provide.
Edit: I found the issue, but still need help. It was the collapsing toolbar that was causing it. If I move the RecyclerView outside the NestedScrollView I can see the items. However The content does not move correctly like the commented out TextViews do in the activity_project_detail.xml. I guess my new question is how do I get a RecyclerView to work inside a NestedScrollView. Thanks you!
ProjectDetailsActivity.java
package com.austine.projectpanda.activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.austine.projectpanda.R;
import com.austine.projectpanda.adapter.TaskAdapter;
import com.austine.projectpanda.data.LocalDatabase;
import com.austine.projectpanda.data.Project;
import com.austine.projectpanda.data.Task;
import java.util.ArrayList;
public class ProjectDetailsActivity extends AppCompatActivity {
private boolean connectionState;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_project_details);
//Sets toolbar and up navigation
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//Gets the connection state from the intent
connectionState = getIntent().getExtras().getBoolean(LocalDatabase.CONNECTION_STATE);
//Gets the projects from the intent
Project project = getIntent().getExtras().getParcelable(LocalDatabase.PROJECT_DETAILS);
//Sets activity title
setTitle(project.getTitle());
//Generates Task arrays
ArrayList<Task> tasksUncompleted = Task.getUncompletedTasks(project.getTasks());
ArrayList<Task> tasksCompleted = Task.getCompletedTasks(project.getTasks());
//TODO: Fix recycler views
RecyclerView recyclerUncompleted = (RecyclerView) findViewById(R.id.detail_uncompleted);
recyclerUncompleted.setLayoutManager(new LinearLayoutManager(this));
recyclerUncompleted.setAdapter(new TaskAdapter(tasksUncompleted));
registerForContextMenu(recyclerUncompleted);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_projects_list, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
TaskAdapter.java
package com.austine.projectpanda.adapter;
import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.austine.projectpanda.R;
import com.austine.projectpanda.data.LocalDatabase;
import com.austine.projectpanda.data.Project;
import com.austine.projectpanda.data.ProjectCardView;
import com.austine.projectpanda.data.Task;
import com.austine.projectpanda.data.TaskView;
import java.util.ArrayList;
public class TaskAdapter extends RecyclerView.Adapter {
private ArrayList<Task> tasks;
public TaskAdapter(ArrayList<Task> tasks) {
this.tasks = tasks;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//Selects the layout used in the Recycler
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_task, parent, false);
return new TaskView(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
TaskView view = (TaskView) holder;
//Gets the views that need to be changed
view.getTitle().setText(tasks.get(position).getTitle());
view.getSubtitle().setText(tasks.get(position).getSubtitle());
view.getCheckbox().setChecked(tasks.get(position).isCompleted());
}
#Override
public int getItemCount() {
Log.e(LocalDatabase.LOG_TAG, "GetItemCount: " + tasks.size());
return tasks.size();
}
}
TaskView.java
package com.austine.projectpanda.data;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import com.austine.projectpanda.R;
import com.austine.projectpanda.activity.ProjectDetailsActivity;
import com.austine.projectpanda.activity.ProjectsListActivity;
import com.austine.projectpanda.activity.WelcomeActivity;
public class TaskView extends RecyclerView.ViewHolder {
private View view;
private TextView title, subtitle;
private CheckBox checkbox;
public TaskView(View view) {
super(view);
//Gets the different parts of a layout
this.view = view;
this.title = (TextView) view.findViewById(R.id.task_title);
this.subtitle = (TextView) view.findViewById(R.id.task_subtitle);
this.checkbox = (CheckBox) view.findViewById(R.id.task_checkbox);
}
public View getView() {
return view;
}
public TextView getTitle() {
return title;
}
public TextView getSubtitle() {
return subtitle;
}
public CheckBox getCheckbox() {
return checkbox;
}
}
activity_project_details.xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_collapsing"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="#+id/detail_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--<TextView
android:layout_width="match_parent"
android:layout_height="#dimen/detail_header_height"
android:paddingLeft="#dimen/spacing_m"
android:gravity="center_vertical"
android:text="#string/details_uncomp"
android:textSize="#dimen/text_body"
android:textColor="#color/text_subheader"/>-->
<android.support.v7.widget.RecyclerView
android:id="#+id/detail_uncompleted"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!--<TextView
android:layout_width="match_parent"
android:layout_height="#dimen/detail_header_height"
android:paddingLeft="#dimen/spacing_m"
android:gravity="center_vertical"
android:text="#string/details_comp"
android:textSize="#dimen/text_body"
android:textColor="#color/text_subheader"/>-->
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
fragment_task.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="#dimen/spacing_xxl"
android:paddingLeft="#dimen/spacing_m"
android:paddingRight="#dimen/spacing_m"
android:gravity="center_vertical">
<CheckBox
android:id="#+id/task_checkbox"
android:layout_width="#dimen/spacing_l"
android:layout_height="#dimen/spacing_l" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/spacing_xl">
<TextView
android:id="#+id/task_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Set Austin on fire"
android:textSize="#dimen/text_subheading"
android:textColor="#color/text"/>
<TextView
android:id="#+id/task_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Light Austin on fire using a Zippo"
android:textSize="#dimen/text_body"
android:textColor="#color/text_subheader"/>
</LinearLayout>
</LinearLayout>
Add this property to the NestedScrollView:
android:fillViewport="true"
First, add the fillViewport property to your NestedScrollView:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fillViewport="true">
In addition, you have to use the setAutoMesureEnabled method in the LayoutManager of the RecyclerView:
LinearLayoutManager linearLayoutManager = new LinearLayoutManager( getActivity() );
linearLayoutManager.setOrientation( LinearLayoutManager.VERTICAL );
linearLayoutManager.setAutoMeasureEnabled( true );
The setAutoMeasureEnabled method is available since 23.2 in the support design library.
it's supper crazy but it work for me.
add one attribute android:padding="16" inside RecycelrView attribute.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/toppers_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/large_space"
/>
please help
When I run my ListFragment actitivy and click on a fragment (either Buick or Mazda), the layout of the fragment I clicked on is supposed to replace and cover the entire screen but the
container containing the list of cars stays on the screen and my fragment layout is shown below it. How can I make my fragment's layout replace the entire screen?
I couldn't post my AVD image showing the screen because I don't have enough reputatons to do
but the screen was showing as below when I clicked on the first item on the list.
Buick
Mazda
Hello! It's a Buick
my Mainactivity
package in.cars.demo;
import android.app.Activity;
import android.os.Bundle;
public class CarsMainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
My ListFragment activity
package in.cars.demo;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class CarsList extends ListFragment {
String[] cars = new String[] { "Buick", "Mazda" };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListAdapter myListAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, cars);
setListAdapter(myListAdapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.cars_container, container, false);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(), getListView().getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
switch (position) {
case 0:
Fragment fragment1 = new Fragment1();
FragmentTransaction transaction1 = getFragmentManager().beginTransaction();
transaction1.replace(R.id.car_fragment, fragment1);
transaction1.addToBackStack(null);
transaction1.commit();
break;
case 1:
Fragment fragment2 = new Fragment2();
FragmentTransaction transaction2 = getFragmentManager().beginTransaction();
transaction2.replace(R.id.car_fragment, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();
break;
}
}
}
Fragment1
package in.cars.demo;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1, container, false);
}
}
Fragment2
package in.cars.demo;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/car_fragment"
android:name="in.cars.demo.CarsList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
cars_container.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="4dp"
android:paddingRight="4dp">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
</LinearLayout>
fragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/frag1TV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello! It's a Buick" />
</LinearLayout>
fragment2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/frag2TV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello! It's a Mazda" />
</LinearLayout>
The problem is that you set the layout_height of your fragment to wrap_content in your main.xml. The visible size will be reduced to the actual size of the fragment.
Change it to match_parent to fill the whole screen:
...
<fragment
android:id="#+id/car_fragment"
android:name="in.cars.demo.CarsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
...
Furthermore use match_parent instead of fill_parent in apps with API Level 8+. See this question for more information.
Edit:
You have to change the container for the Fragments. The Fragment set with the tag will be static. Every fragment will be set in addition to this container. To have a dynamic approach use a FrameLayout. Now you can replace the fragment which was in there before.
...
<FrameLayout
android:id="#+id/car_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
...
To show your CarsList you have to do a Fragment transaction in your Activity.
getFragmentManager() / getSupportFragmentManager()
.beginTransaction()
.replace(R.id.car_fragment, new CarsList())
.addToBackstack(null)
.commit();
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:clickable="true"
android:orientation="vertical">
Try to setUp a color background to your fragment. In this way the background covers the entire space.
It is a little bit late, but maybe I will help someone else. The problem is with 'fragment' in your activity xml layout file (main.xml). You have to change:
<fragment
android:id="#+id/car_fragment"
android:name="in.cars.demo.CarsList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
to
<fragment
android:id="#+id/car_fragment"
android:name="in.cars.demo.CarsList"
android:layout_width="match_parent"
android:layout_height="match_parent"/>