Moving FloatingActionButton when scrolling up CollapsingToolbarLayout - android

I have a layout with CollapsingToolbarLayout, a RecyclerView and a FloactingActionButton.
The idea is expand my Toolbar when the user is scrolling RecyclerView down and retracting it when scrolling up.
But when I scroll up my RecyclerView, the AppBarLayout retracts and my FloactingActionButton disappears.
I want to show it again in some other place in my screen like the botton.
How can I do It?
This is my screen:
Before Scrolling down - My FloactingActionButton is there.
After scrolling down - There's no room left for FloactingActionButton, so it dismiss. I just want to show it on botton of screen.
Code of my Layout XML :
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="192dp">
<android.support.design.widget.CollapsingToolbarLayout
android:elevation="4dp"
android:id="#+id/collapsing_toolbar"
android:background="#color/primary"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
style="#style/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
app:layout_anchor="#id/app_bar_layout"
app:layout_anchorGravity="bottom|right|end" />
Code of my Activity
public class MainActivityRecycler extends AppCompatActivity implements OnDataSelected {
private CollapsingToolbarLayout collapsingToolbarLayout;
public void onDataSelected(View view, int position) {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_recycler);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbarLayout.setTitle("Collapsing");
//collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(android.R.color.transparent));
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
ArrayList<String> details = new ArrayList<String>();
details.add("Main Facilities");
details.add("Restaurants");
details.add("Shops");
details.add("Motel");
details.add("Forecourt");
DetailsAdapter mAdapter = new DetailsAdapter(this, null, details);
recyclerView.setAdapter(mAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
class DetailsAdapter extends RecyclerView.Adapter<DetailsAdapter.ViewHolder> {
private List<String> cars;
private Context context;
private OnDataSelected onDataSelected;
public DetailsAdapter(Context context, OnDataSelected onDataSelected, List<String> cars) {
this.context = context;
this.onDataSelected = onDataSelected;
this.cars = cars;
}
#Override
public DetailsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String car = cars.get(position);
holder.textViewTitleCar.setText(car);
}
#Override
public int getItemCount() {
return cars.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewTitleCar;
public ViewHolder(View view) {
super(view);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
treatOnDataSelectedIfNecessary(v, getAdapterPosition());
}
});
textViewTitleCar = (TextView) view.findViewById(R.id.info_text);
}
}
private void treatOnDataSelectedIfNecessary(View view, int position) {
if (onDataSelected != null) {
onDataSelected.onDataSelected(view, position);
}
}
}
}

You can easily create any behavior for your item. You will need to realize ScrollListener for your AppBarLayout. More example of custom behavoir - Github
I hope correctly understood and helped.
public class FlexibleSpaceExampleActivity extends AppCompatActivity
implements AppBarLayout.OnOffsetChangedListener {
private static final int PERCENTAGE_TO_SHOW_IMAGE = 20;
private View mFab;
private int mMaxScrollSize;
private boolean mIsImageHidden;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flexible_space);
mFab = findViewById(R.id.flexible_example_fab);
Toolbar toolbar = (Toolbar) findViewById(R.id.flexible_example_toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
onBackPressed();
}
});
AppBarLayout appbar = (AppBarLayout) findViewById(R.id.flexible_example_appbar);
appbar.addOnOffsetChangedListener(this);
}
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (mMaxScrollSize == 0)
mMaxScrollSize = appBarLayout.getTotalScrollRange();
int currentScrollPercentage = (Math.abs(i)) * 100
/ mMaxScrollSize;
if (currentScrollPercentage >= PERCENTAGE_TO_SHOW_IMAGE) {
if (!mIsImageHidden) {
mIsImageHidden = true;
ViewCompat.animate(mFab).scaleY(0).scaleX(0).start();
/**
* Realize your any behavior for FAB here!
**/
}
}
if (currentScrollPercentage < PERCENTAGE_TO_SHOW_IMAGE) {
if (mIsImageHidden) {
mIsImageHidden = false;
ViewCompat.animate(mFab).scaleY(1).scaleX(1).start();
/**
* Realize your any behavior for FAB here!
**/
}
}
}
public static void start(Context c) {
c.startActivity(new Intent(c, FlexibleSpaceExampleActivity.class));
}
}

Use Floating Action Button and set property as I have set. It is very easy to display FAB in collapsingToolbarLayout.
<android.support.design.widget.AppBarLayout
android:id="#+id/activity_main_appbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="InconsistentLayout">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/activity_main_collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2196f3"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
tools:ignore="InconsistentLayout">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/paris"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="#+id/activity_main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/transparent"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/activity_main_nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:ignore="InconsistentLayout">
<android.support.v7.widget.RecyclerView
android:id="#+id/activity_main_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:src="#drawable/ic_call_black_24dp"
app:layout_anchor="#id/activity_main_appbar"
app:layout_anchorGravity="bottom|right|end" />

Related

Scroll behaviour of Tablayout with ActionBar is not working properly

I am trying to implement behaviour like whatsApp.
Expected Behaviour :
When user scrolles the list Tablayout scrolls up with action bar.
ActionBar hides and insted Tablayout takes it's place.
What's happening :
Everything is working good with ActionBar and Tablayout but when scrolled up place of Tablayout is taken by white space.
ScreenShot 1, ScreenShot 2
and I am trying to remove that white space but couldn't.
Below is my Activity and Fragment code
MainActivity.java
public class ViewPagerActivity extends AppCompatActivity {
private TabLayout tabLayout;
private LockableViewPager viewPager;
private Toolbar toolbar;
private MaterialSearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_pager);
searchView = findViewById(R.id.search_view);
tabLayout = findViewById(R.id.tabs);
toolbar = findViewById(R.id.toolbar);
viewPager = findViewById(R.id.viewPager);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("WhatsApp");
toolbar.setTitleTextColor(Color.WHITE);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
searchView.setOnSearchViewListener(new MaterialSearchView.SearchViewListener() {
#Override
public void onSearchViewShown() {
tabLayout.setVisibility(View.GONE);
TranslateAnimation animate = new TranslateAnimation(0, -tabLayout.getWidth(), 0, 0);
tabLayout.setAnimation(animate);
viewPager.setSwipeAble(false);
}
#Override
public void onSearchViewClosed() {
tabLayout.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(0, 0, 0, tabLayout.getHeight());
tabLayout.setAnimation(animate);
viewPager.setSwipeAble(true);
}
});
}
private void setupViewPager(ViewPager viewPager) {
PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab1Fragment(), "CHATS");
adapter.addFragment(new Tab2Fragment(), "STATUS");
adapter.addFragment(new Tab2Fragment(), "CALLS");
viewPager.setAdapter(adapter);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
if (searchView.isSearchOpen()) {
searchView.closeSearch();
viewPager.setSwipeAble(true);
} else {
super.onBackPressed();
}
}
}
activity_main.xml
<RelativeLayout 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/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="6dp">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:elevation="0dp"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
</androidx.appcompat.widget.Toolbar>
<com.miguelcatalan.materialsearchview.MaterialSearchView
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_below="#+id/toolbar_container"
android:layout_marginTop="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:elevation="0dp"
app:tabIndicatorColor="#ffffff"
app:tabMode="fixed"
app:tabSelectedTextColor="#ffffff"
app:tabTextColor="#d3d3d3" />
</FrameLayout>
<com.example.fragmentcontroller.view_pager.LockableViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar_container"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
Tab1Fragment.java
public class Tab1Fragment extends Fragment implements View.OnClickListener {
private float mToolbarHeight;
public Tab1Fragment() {
// Required empty public constructor
}
private View view;
private MaterialSearchView searchView;
private ArrayList<ModelD> modelDArrayList;
private RecyclerView recyclerView;
private Toolbar toolbar;
private FrameLayout toolbarContainer;
private TabLayout tabs;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tab1, container, false);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
searchView = getActivity().findViewById(R.id.search_view);
toolbar = getActivity().findViewById(R.id.toolbar);
recyclerView = view.findViewById(R.id.recyclerView);
toolbarContainer = getActivity().findViewById(R.id.toolbar_container);
tabs = getActivity().findViewById(R.id.tabs);
mToolbarHeight = Utils.getToolbarHeight(getContext());
searchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (newText.equals("")) {
bindList(modelDArrayList);
} else {
ArrayList<ModelD> arrayList = new ArrayList<>();
for (int i = 0; i < modelDArrayList.size(); i++) {
if
(modelDArrayList.get(i).getName().toLowerCase().contains((newText).toLowerCase())) {
arrayList.add(modelDArrayList.get(i));
}
}
bindList(arrayList);
}
return false;
}
});
modelDArrayList = new ArrayList<>();
bindList(modelDArrayList);
recyclerView.setOnScrollListener(new HidingScrollListener(getContext()) {
#Override
public void onHide() {
if (!searchView.isSearchOpen()) {
hideViews();
}
}
#Override
public void onMoved(int distance) {
if (!searchView.isSearchOpen()) {
toolbarContainer.setTranslationY(-distance);
}
}
#Override
public void onShow() {
showViews();
}
});
}
private void hideViews() {
toolbar.animate().translationY(-toolbar.getHeight()).setInterpolator(new
AccelerateInterpolator(2));
// tabs.animate().translationY(-mToolbarHeight).setInterpolator(new
AccelerateInterpolator(2)).start();
}
private void showViews() {
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
// tabs.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();
}
private void bindList(ArrayList<ModelD> arrayList) {
if (arrayList.isEmpty()) {
for (int i = 0; i < 20; i++) {
ModelD modelD = new ModelD();
modelD.setName("Name " + i);
arrayList.add(modelD);
}
}
DAdapter adapter = new DAdapter(getContext(), arrayList);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_search, menu);
MenuItem item = menu.findItem(R.id.action_search);
if (searchView != null) {
searchView.setMenuItem(item);
}
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public void onClick(View v) {
}
}
tab1_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".view_pager.fragments.Tab1Fragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
You should use CoordinatorLayout
The app:layout_scrollFlags="scroll|enterAlways|snap", app:layout_behavior="#string/appbar_scrolling_view_behavior" that you are using only work in CoordinatorLayout.
A proper implementation will somewhat look like below.
<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:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:elevation="0dp"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
</androidx.appcompat.widget.Toolbar>
<com.miguelcatalan.materialsearchview.MaterialSearchView
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways|snap" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:elevation="0dp"
app:tabIndicatorColor="#ffffff"
app:tabMode="fixed"
app:layout_scrollFlags="noScroll"
app:tabSelectedTextColor="#ffffff"
app:tabTextColor="#d3d3d3" />
</com.google.android.material.appbar.AppBarLayout>
<com.example.fragmentcontroller.view_pager.LockableViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
check this link, if you want a more detailed explanation.

RecyclerView strange background color

As the title says, I have a problem with RecyclerView and CardView.
During the development process, dark frames appeared over RecyclerView that isn't defined anywhere. Any advice how can I get rid of it?
CardView has two textViews and MapView.
SingleRun is a simple object with 2 Strings.
MainActivity
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Main Activity onCreate");
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(new SingleRunsAdapter(new SingleRunProvider().readData(), getApplicationContext()));
CardViewRecyclerViewItem
CardViewRecyclerViewItem
public class CardViewRecyclerViewItem extends CardView {
protected MapView mapView;
protected TextView distance;
protected TextView time;
public CardViewRecyclerViewItem(Context context) {
this(context, null);
}
public CardViewRecyclerViewItem(Context context, AttributeSet attrs) {
super(context, attrs);
View view = LayoutInflater.from(getContext()).inflate(R.layout.card_view_single_run, this);
mapView = (MapView) view.findViewById(R.id.single_run_map_mapview);
distance = (TextView) view.findViewById(R.id.details_distance_textview);
time = (TextView) view.findViewById(R.id.details_time_textview);
}
public void cardViewOnCreate(Bundle savedInstanceState) {
if (mapView != null) {
mapView.onCreate(savedInstanceState);
}
}
public void cardViewOnResume() {
if (mapView != null) {
mapView.onResume();
}
}}
CardViewHolder
public class CardViewHolder extends RecyclerView.ViewHolder {
private CardViewRecyclerViewItem mCardViewRecyclerViewItem;
public CardViewHolder(CardViewRecyclerViewItem cardViewRecyclerViewItem) {
super(cardViewRecyclerViewItem);
mCardViewRecyclerViewItem = cardViewRecyclerViewItem;
}
public void cardViewRecyclerViewItemOnResume() {
if (mCardViewRecyclerViewItem != null) {
mCardViewRecyclerViewItem.cardViewOnResume();
}
}}
SingleRunAdapter
public class SingleRunsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
Context context;
private final List<SingleRun> singleRuns;
public SingleRunsAdapter(List<SingleRun> singleRuns, Context context) {
this.singleRuns = singleRuns;
this.context = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CardViewRecyclerViewItem cardViewRecyclerViewItem = new CardViewRecyclerViewItem(context);
cardViewRecyclerViewItem.cardViewOnCreate(null);
return new CardViewHolder(cardViewRecyclerViewItem);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
CardViewHolder cardViewHolder = (CardViewHolder) viewHolder;
cardViewHolder.cardViewRecyclerViewItemOnResume();
}
#Override
public int getItemCount() {
return singleRuns.size();
}}
activity_main.xml
<android.support.design.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"
tools:context="com.coderspeak.lightweightrunningtracker.single_run.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
content_main.xml
<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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.coderspeak.lightweightrunningtracker.single_run.MainActivity"
tools:showIn="#layout/activity_main">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
</LinearLayout>
card_view_single_run.xml
<android.support.v7.widget.CardView xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.gms.maps.MapView xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/single_run_map_mapview"
android:layout_width="match_parent"
android:layout_height="144dp"
map:liteMode="true"
map:mapType="normal"
tools:context=".MapsActivity" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:layout_margin="8dp">
<TextView
android:id="#+id/single_run_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="00:12:34"
android:textAlignment="center" />
<TextView
android:id="#+id/single_run_distance"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="3.14km"
android:textAlignment="center" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
How it looks:
RecyclerView with strange background color
If you will comment both LinearLayouts with content in card_view_single_run.xml and mapView line in CardViewRecyclerViewItem you will see this:
THIS
This is more strange in my opinion, because even if empty cards, recycler have some background.
Thank you for any help. If necessary, I can provide more code.
The best way to diagnose this kind of errors IMO is using Layout Inspector tool in Android Studio:
Try the following
in your MainActivity
change context from getApplicationContext() to MainActivity.this
RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(new SingleRunsAdapter(new SingleRunProvider().readData(), MainAcitivity.this));

Content not shown in Fragment TabLayout Android

I have spent the whole day trying to fix this but I couldn't.
In my android application, I have a mainActivity HomePageServices, which has 3 tabs : HomeActivity, ProfileActivity, and SettingsActivity.
These tabs are Fragments called by TabLayout and ViewPager.
The transition between tabs works perfectly, but the problem is I have nothing displayed in any of the fragments!
I want to dispaly a RecyclerView with a GridLayout of cards in HomeActivity.
Here is what I have done so far:
HomePageServices:
public class HomePageServices extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
//Toolbar
initCollapsingToolbar();
//tabs
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new
TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
/**
* Initializing collapsing toolbar
* Will show and hide the toolbar title on scroll
*/
private void initCollapsingToolbar() {
final CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(" ");
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
appBarLayout.setExpanded(true);
// hiding & showing the title when toolbar expanded & collapsed
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
collapsingToolbar.setTitle(getString(R.string.app_name));
isShow = true;
} else if (isShow) {
collapsingToolbar.setTitle(" ");
isShow = false;
}
}
});
}
}
HomePageServices XML layout:
<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:background="#android:color/white"
android:fitsSystemWindows="true"
>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="#dimen/detail_backdrop_height"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:expandedTitleTextAppearance="#android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<TextView
android:id="#+id/love_music"
android:layout_width="237dp"
android:layout_height="wrap_content"
android:text="#string/backdrop_title"
android:textColor="#android:color/white"
android:textSize="#dimen/backdrop_title"
android:gravity="center_horizontal|center"
android:layout_gravity="center_horizontal|center"
android:layout_centerHorizontal="true" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:layout_centerVertical="true">
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tab_layout">
<android.support.design.widget.TabItem
android:icon="#drawable/ic_home_white_24dp"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<android.support.design.widget.TabItem
android:icon="#drawable/ic_perm_identity_white_24dp"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<android.support.design.widget.TabItem
android:icon="#drawable/ic_settings_white_24dp"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.v7.widget.Toolbar>
</RelativeLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
PagerAdapter:
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
ProfileActivity tab1 = new ProfileActivity();
return tab1;
case 1:
SettingsActivity tab2 = new SettingsActivity();
return tab2;
case 2:
HomeActivity tab3=new HomeActivity();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
HomeActivity
public class HomeActivity extends Fragment {
private RecyclerView recyclerView;
public static ServicesAdapter homeAdapter;
public static List<Service> serviceList;
final static String ADD_NEW_ITEM_TYPE="add new item";
public HomeActivity () {
//empty constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//cards
View rootView=inflater.inflate(R.layout.activity_home2, container, false);
TextView tt= (TextView) rootView.findViewById(R.id.textView3);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
serviceList = new ArrayList<>();
homeAdapter = new ServicesAdapter(this.getContext(), serviceList);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
initServices();
recyclerView.setAdapter(homeAdapter);
Log.d("show me what you got", serviceList.toString());
Toast.makeText(this.getContext(),"Hiiiiiiiiiiiiiiii from the other side",Toast.LENGTH_SHORT).show();
return rootView;
}
public static class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
int spanCount;
int spacing;
boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
}
private int dpToPx(int dp) {
Resources r = getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
public void initServices () {
Service a = new Service(ADD_NEW_ITEM_TYPE);
serviceList.add(a);
//just for testing
a = new Service("Signaler a dysfonctionnement");
serviceList.add(a);
a = new Service("Activités inter-employés");
serviceList.add(a);
homeAdapter.notifyDataSetChanged();
}
}
HomeActivity XML layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_home2"
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="HomeActivity">
<include layout="#layout/content_main"
/>
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_marginStart="42dp"
android:id="#+id/textView3" />
</RelativeLayout>
And finally the RecyclerView layout:
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="HomePage.HomeActivity"
tools:showIn="#layout/activity_home2">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:scrollbars="vertical"
android:paddingLeft="5dp" />
</RelativeLayout>
PS: Before creating the tabs, the RecyclerViewer successfully displayed the cards in an Activity without any problems.

RecyclerView 2 Columns with CardView

I have a problem with my layout. I'm trying to do something like this:
For now, i have a RecyclerView with a CardView inside it. in the CardView I have put an ImageView and a TextView but I don't know why but the CardView is more height than ImageView inside it.
Here is The code and a Sample Image.
And Here is the code: Activity
public class AddRoomActivity extends AppCompatActivity implements View.OnClickListener {
private View snackView;
private FloatingActionButton fabDoneAddRoom;
private EditText etRoomName;
private String roomName = null;
public final static String KEY_PI_IP = "MyPi_IP";
private final static String KEY_ROOM = "myRoom";
private final static String KEY_ROOM_TYPE = "myRoom_Type";
private RecyclerView typeRecyclerView;
private GridLayoutManager layoutManager;
private AddRoomActivity.TypeAdapter adapter;
private String myPi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_room);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fabDoneAddRoom = (FloatingActionButton) findViewById(R.id.doneAddRoom);
fabDoneAddRoom.setOnClickListener(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
etRoomName = (EditText) findViewById(R.id.addRoomName);
myPi = getIntent().getStringExtra(KEY_PI_IP);
layoutManager = new GridLayoutManager(this, 2);
typeRecyclerView = (RecyclerView) findViewById(R.id.recyclerTypeRoom);
typeRecyclerView.setHasFixedSize(true);
typeRecyclerView.setLayoutManager(layoutManager);
// specify an adapter (see also next example)
adapter = new TypeAdapter(getResources().getStringArray(R.array.roomTypeName));
typeRecyclerView.setAdapter(adapter);
}
void showToastMessage(String message) {
Snackbar.make(snackView, message, Snackbar.LENGTH_LONG).show();
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.doneAddRoom) {
snackView = v;
String myString = etRoomName.getText().toString();
if (myString.length() > 0) {
roomName = myString.substring(0, 1).toUpperCase() + myString.substring(1);
addRoomToPi();
} else {
showToastMessage(getString(R.string.noNameRoom));
}
}
}
private void addRoomToPi() {
Integer ret = -1;
try {
ret = (Integer) new RaspberryTCPClient(myPi, getResources(), RaspberryTCPClient.TYPE_ADD_ROOM, roomName, XMLRoom.TYPE_KITCHEN_ROOM).execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if (ret == RaspberryTCPClient.OPERATION_DONE) {
showToastMessage(getString(R.string.roomAdded));
Intent data = new Intent();
data.putExtra(KEY_ROOM, roomName);
setResult(Activity.RESULT_OK, data);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
}, 1500);
} else {
showToastMessage(getString(R.string.addRoomError));
}
}
private class TypeAdapter extends RecyclerView.Adapter<AddRoomActivity.TypeAdapter.ViewHolder> {
private String[] myData;
public TypeAdapter(String[] roomList) {
myData = roomList;
}
public void onItemClick(int position) {
}
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView tvType;
public CardView cvRoomCard;
public ImageView imgRoomType;
public ViewHolder(View vCard) {
super(vCard);
cvRoomCard = (CardView) vCard;
tvType = (TextView) vCard.findViewById(R.id.tvTypeName);
imgRoomType = (ImageView) vCard.findViewById(R.id.img_roomType);
}
}
#Override
public AddRoomActivity.TypeAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.type_room_recycler_view, parent, false);
// set the view's size, margins, paddings and layout parameters
//...
AddRoomActivity.TypeAdapter.ViewHolder vh = new AddRoomActivity.TypeAdapter.ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(AddRoomActivity.TypeAdapter.ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.tvType.setText(myData[position]);
switch (position) {
case XMLRoom.TYPE_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_room_sqr);
break;
case XMLRoom.TYPE_BED_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_bedroom_sqr);
break;
case XMLRoom.TYPE_GARDEN_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_garden_sqr);
break;
case XMLRoom.TYPE_KITCHEN_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_kitchen_sqr);
break;
case XMLRoom.TYPE_LIVING_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_living_room_sqr);
break;
case XMLRoom.TYPE_SWIMMING_POOL_ROOM:
holder.imgRoomType.setImageResource(R.drawable.img_swimming_pool_sqr);
break;
}
holder.cvRoomCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClick(position);
}
});
}
#Override
public int getItemCount() {
return myData.length;
}
}
The MainLayout
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="90dp"
android:layout_marginTop="#dimen/toolbar"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true">
<TextView
android:id="#+id/tvAddRoom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_margin="5dp"
android:gravity="center"
android:text="#string/textAddRoom"
android:textColor="#color/primary_text"
android:textSize="20dp"
android:textStyle="bold" />
<android.support.design.widget.TextInputLayout
android:id="#+id/inputaddRoomName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/tvAddRoom"
android:layout_gravity="center"
android:layout_margin="5dp">
<EditText
android:id="#+id/addRoomName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/prompt_RoomName"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerTypeRoom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/inputaddRoomName"
android:scrollbars="vertical" />
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/doneAddRoom"
android:layout_width="#dimen/fab_Dimension"
android:layout_height="#dimen/fab_Dimension"
android:layout_gravity="bottom|center"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#drawable/ic_done" />
</android.support.design.widget.CoordinatorLayout>
and The View Layout:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp">
<ImageView
android:id="#+id/img_roomType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:src="#drawable/img_room" />
<TextView
android:id="#+id/tvTypeName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="center"
android:textColor="#android:color/white"
android:textSize="20sp" />
</android.support.v7.widget.CardView>
Extracted required info from the accepted answer in case URL becomes invalid in future and to save time.
GridLayoutManager is used to display the RecyclerView in Grid manner instead of list.
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(mLayoutManager);
Kotlin version:
recyclerView.apply {
layoutManager = GridLayoutManager(this, 2)
}
You can use this code simply
<android.support.v7.widget.RecyclerView
app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="2"/>
With androidX libraries simply do:
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"/>
for Horizontal recycler view, it works for me
layoutManagerSuperCategories = new GridLayoutManager(context,2,LinearLayoutManager.HORIZONTAL,false);
rv_superCategories.setLayoutManager(layoutManagerSuperCategories);
use "0dp" in layout_width and layout_height for putting views in it's position.
like this:
android:layout_width="0dp"
and use Guidelines in your xml.
<ImageView
android:id="#+id/img_roomType"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:src="#drawable/img_room" />
<TextView
android:id="#+id/tvTypeName"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:gravity="center"
android:textColor="#android:color/white"
android:textSize="20sp" />
this is NOT true code, u have to use Guidelines.

First element in ViewPager is displayed incorrectly

I'm using RecyclerView to display list of elements and from that list u can go to detailed screen, which is view pager fragment. My problem is that first element I navigate to (from RecyclerView) is displayed incorrectly - it has NestedScrollView, which I cannot fully scroll down. If I swype left or right to next pages, they are fine, it's always one that is loaded as first.
My Adapter class is following;
public class ApodViewAdapter extends FragmentStatePagerAdapter {
private ArrayList<APOD> mDataset;
public ApodViewAdapter(FragmentManager fm, ArrayList<APOD> apodsList) {
super(fm);
setData(apodsList);
}
public void setData(ArrayList<APOD> apodsList){
if(apodsList!=null){
this.mDataset= apodsList;
notifyDataSetChanged();
}
}
#Override
public Fragment getItem(int position) {
return new ApodViewFragment().newInstance(mDataset.get(position), position);
}
#Override
public int getCount() {
return mDataset.size();
}
}
Fragment Activity:
public class ApodViewFragment extends Fragment implements DataInterface, AppBarLayout.OnOffsetChangedListener {
private ImageView mApodImageView;
private TextView mTextView;
private Toolbar mToolbar;
private AppBarLayout mAppBarLayout;
private TextView mTitle;
private FrameLayout mContentFl;
private APOD mApodElement;
private static final String KEY_CONTENT = "ApodViewFragment:Content";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) {
mApodElement = (APOD) savedInstanceState.getSerializable(KEY_CONTENT);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(KEY_CONTENT, mApodElement);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_apod_material, container, false);
mApodImageView = (ImageView) rootView.findViewById(R.id.apod_view_apod_iv);
mTextView = (TextView) rootView.findViewById(R.id.apod_view_text_tv);
mTitle = (TextView) rootView.findViewById(R.id.apod_fragment_title_tv);
mContentFl = (FrameLayout) rootView.findViewById(R.id.fragment_apod_fl);
mToolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
mAppBarLayout = (AppBarLayout) rootView.findViewById(R.id.app_bar_layout);
mAppBarLayout.addOnOffsetChangedListener(this);
ViewTreeObserver vto = mContentFl.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
setHeroImageMaxHeight();
ViewTreeObserver obs = mContentFl.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
setData();
return rootView;
}
public static ApodViewFragment newInstance(APOD apodElement, int position) {
ApodViewFragment fragment = new ApodViewFragment();
fragment.mApodElement = apodElement;
return fragment;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void saveData(APOD apodElement) {
}
#Override
public void readData() throws IOException {
}
private void setData() {
if(mApodElement.getMedia_type().equals("video")){
Picasso.with(getActivity()).load(R.drawable.videoplaceholder).into(mApodImageView);
}else{
Picasso.with(getActivity()).load(mApodElement.getUrl()).into(mApodImageView);
}
mTextView.setText(mApodElement.getExplanation());
mTitle.setText(mApodElement.getTitle());
}
private void setHeroImageMaxHeight(){
int screenHeight = ImageHelper.getDisplayHeight(getActivity());
mToolbar.getLayoutParams().height = screenHeight - mContentFl.getHeight();
mToolbar.requestLayout();
}
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
float minimalTextSize = getActivity().getResources().getDimensionPixelSize(R.dimen.apod_view_title_scrolling_text_size);
float maximumTextSize = getActivity().getResources().getDimensionPixelSize(R.dimen.apod_view_title_default_text_size);
float absolut_offset = Math.abs(offset);
float text_size_difference = maximumTextSize - minimalTextSize;
float scale = (absolut_offset) / (appBarLayout.getHeight() - absolut_offset);
if (offset < 0) {
float result = maximumTextSize - (scale * text_size_difference);
mTitle.setTextSize(FontHelper.pixelsToSp(getActivity(), result));
} else {
mTitle.setTextSize(FontHelper.pixelsToSp(getActivity(), maximumTextSize));
}
}
}
And XML layout file
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/apod_fragment_ctl"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleMarginStart="16dp"
android:fitsSystemWindows="true">
<ImageView
android:id="#+id/apod_view_apod_iv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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">
<RelativeLayout
android:layout_width="wrap_content"
android:fitsSystemWindows="true"
android:layout_height="wrap_content">
<TextView
android:id="#+id/apod_fragment_title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="#dimen/apod_view_title_default_text_size"
android:layout_alignParentBottom="true"
app:layout_collapseMode="pin"
/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:background="#android:color/holo_purple"
android:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="#+id/fragment_apod_fl"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:layout_gravity="center_vertical"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:text="TITLE"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:textAppearance="#style/TextAppearance.AppCompat.Headline"/>
<TextView
android:id="#+id/apod_view_text_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
app:layout_anchor="#id/cardview"
app:layout_anchorGravity="top|right|end"
android:src="#drawable/ic_rocket_em_blank"
android:layout_margin="16dp"
app:backgroundTint="#android:color/holo_purple"
style="#style/FabStyle"/>
</android.support.design.widget.CoordinatorLayout>
I'd say that reason must be somewhere in Adapter or fragment's methods, which create new Fragment, but can't really find it. Any help appreciated, cheers!

Categories

Resources