AutoScroll Toolbar text when using CollapsingToolbarLayout - android

I have CollapsingToolbarLayout with long title with Toolbar inside.
Because of title is too long, its end is replaced by three dots. The problem is when CollapsingToolbarLayout is collapsed and Toolbar has CollapsingToolbarLayout's title, is still has three dots. I want to make title of Toolbar autoscroll if it's long.
My XML:
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/recyclerview_background"
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="190dp"
android:fitsSystemWindows="true"
app:contentScrim="#color/colorAppPrimary"
app:expandedTitleMarginEnd="8dp"
app:expandedTitleMarginStart="36dp"
app:expandedTitleTextAppearance="#style/TextAppearance.AppCompat.Title"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<RelativeLayout
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="190dp"
android:fitsSystemWindows="true">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/material_bg_3"
app:layout_collapseMode="parallax" />
<ImageView
android:id="#+id/imageViewPhoto"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="?attr/actionBarSize"
app:layout_collapseMode="parallax" />
<TextView
android:id="#+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="false"
android:layout_below="#+id/imageViewPhoto"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:text=""
android:textColor="#color/white"
android:textSize="16sp" />
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:ellipsize="marquee"
android:fitsSystemWindows="true"
android:gravity="top"
app:layout_collapseMode="pin">
<TextView
android:id="#+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:gravity="center"
android:textColor="#color/white"
android:textSize="20dp"
android:textStyle="bold"
android:visibility="gone" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
style="#style/AppTheme.TabLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/white"
app:tabIndicatorColor="#color/colorAppPrimary"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_below="#id/tabs" />
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
Expanded CollapsingToolbarLayout:
Toolbar:

I have tested it and it is working. Have a look and see if it suits your need.
Add this text in your Toolbar View
<TextView
android:id="#+id/toolbar_title"
android:text="This will run the marquee animation forever"
android:textSize="#dimen/abc_text_size_title_material_toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:singleLine="true" />
then in your activity class, add this line of code after
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
My Full code is below.
layout file
<?xml version="1.0" encoding="utf-8"?>
<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"
android:fitsSystemWindows="true"
tools:context="com.inducesmile.toolbartesting.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"
android:scrollHorizontally="true"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<TextView
android:id="#+id/toolbar_title"
android:text="This will run the marquee animation forever"
android:textSize="#dimen/abc_text_size_title_material_toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:singleLine="true" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
and the Activity class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#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_main, 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);
}
}
This solution was partly from here
Update
I have add addOnOffsetChangedListener to AppBarLayout to detect when the CollapsingToolbarLayout is expanded or collapsed.
First instantiate the AppBarLayout
private AppBarLayout mAppBarLayout;
private TextView toolBarText;
the inside onCreate method
toolBarText = (TextView)findViewById(R.id.toolbar_title);
mAppBarLayout = (AppBarLayout)findViewById(R.id.app_bar);
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
Toast.makeText(MainActivity.this, "Vert " + verticalOffset, Toast.LENGTH_LONG).show();
if(verticalOffset == 0){
// Expanded
toolBarText.setText("");
}else{
//collapsed
}
}
});
Check if it works for you

to remove the title of Toolbar when CollapsingToolbarLayout expanded add this snippet:
final CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout)
findViewById(R.id.collapsing_toolbar_layout);
mAppBar.addOnOffsetChangedListener(new OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (collapsingToolbar.getHeight() + verticalOffset <
2 * ViewCompat.getMinimumHeight(collapsingToolbar)) {
mTitleTV.setVisibility(View.VISIBLE);
mTitleTV.animate().alpha(1).setDuration(600);
} else {
mTitleTV.animate().alpha(0).setDuration(600);
}
}
});

Related

RecyclerView inside NestedScrollView scrolling issue

Iv seen many threads like that, but non of them helped me. When i use RecyclerView inside NestedScrollView im having scrolling issues - stuck. I know its because that is scroll inside scroll,
rv.setNestedScrollingEnabled(false); is not working for me.
on few thread there was information that NestedScrollView dont have to be used - but then toolbar is not collapsing.
My XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:expandedTitleGravity="bottom"
app:expandedTitleMarginStart="#dimen/activity_vertical_margin"
app:expandedTitleTextAppearance="#style/CollapsedAppBarTopic"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="parallax">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/activity_vertical_margin">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:alpha="0.5"
app:layout_collapseMode="parallax"
app:srcCompat="#drawable/logo_white" />
<TextView
android:id="#+id/yourVotes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_toLeftOf="#+id/votesSum"
android:layout_toStartOf="#+id/votesSum"
android:text="#string/YourVotes"
android:textAlignment="viewStart" />
<TextView
android:id="#+id/votesSum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:text="1" />
</RelativeLayout>
</FrameLayout>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbarDetails"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TableLayout
android:id="#+id/tableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorBackground">
<TableRow>
<TextView
android:layout_weight="1"
android:elevation="1dp"
android:text="#string/VotesSum"
android:textAlignment="center" />
<TextView
android:layout_weight="1"
android:elevation="0dp"
android:text="#string/TodayVotes"
android:textAlignment="center" />
<TextView
android:layout_weight="1"
android:text="#string/TodayAdded"
android:textAlignment="center" />
</TableRow>
<TableRow>
<TextView
android:layout_weight="1"
android:text="1"
android:textAlignment="center" />
<TextView
android:id="#+id/textView3"
android:layout_weight="1"
android:text="2"
android:textAlignment="center" />
<TextView
android:layout_weight="1"
android:text="3"
android:textAlignment="center" />
</TableRow>
</TableLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/tracks_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="60dp"
android:background="#color/colorBackground" />
<ProgressBar
android:id="#+id/progressBarDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:background="#android:color/transparent" />
</LinearLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/colorPrimary"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#drawable/bottom_nav_colors"
app:itemTextColor="#drawable/bottom_nav_colors"
app:menu="#menu/navigation" />
</android.support.design.widget.CoordinatorLayout>
So, please help me to make that work
public class PlaylistDetailActivityWithoutFragmet extends AppCompatActivity {
private TextView votesLeft;
private RecyclerView lvTracks;
private SinglePlaylistFragment_.OnFragmentInteractionListener mListener;
SinglTracksAdapter recyclerViewAdapter;
final ArrayList<PlaylistTracks> playlistsTracks = new ArrayList<PlaylistTracks>();
final ArrayList<PlaylistTracks> playlistsTracks2 = new ArrayList<PlaylistTracks>();
int lastId = 0;
private boolean loading = true;
ProgressBar progressBar;
Toolbar toolbarDetails;
CollapsingToolbarLayout collapsingToolbarLayout;
int firstVisibleItem, visibleItemCount, totalItemCount;
private int visibleThreshold = 2;
final LinearLayoutManager llm = new LinearLayoutManager(this);
int height;
NestedScrollView nestedScrollView;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
// mTextMessage.setText(R.string.Playlist);
return true;
case R.id.navigation_dashboard:
// mTextMessage.setText(R.string.Statistics);
return true;
case R.id.navigation_notifications:
// mTextMessage.setText(R.string.Users);
return true;
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_coordinator_layout);
toolbarDetails = (Toolbar) findViewById(R.id.toolbarDetails);
collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
setSupportActionBar(toolbarDetails);
collapsingToolbarLayout.setTitle(playlistName);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbarDetails.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_black_24dp));
toolbarDetails.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mWebSocketClient.close();
onBackPressed();
}
});
llm.setOrientation(LinearLayoutManager.VERTICAL);
// nestedScrollView = (NestedScrollView) findViewById(R.id.nestedScroll);
lvTracks = (RecyclerView) findViewById(R.id.tracks_recycler_view);
lvTracks.setLayoutManager(llm);
lvTracks.setNestedScrollingEnabled(false);
// nestedScrollView.setSmoothScrollingEnabled(true);
progressBar = (ProgressBar) findViewById(R.id.progressBarDetails);
progressBar.setVisibility(View.GONE);
loading = true;
getTracks();
lvTracks.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = llm.getChildCount();
totalItemCount = llm.getItemCount();
firstVisibleItem = llm.findFirstVisibleItemPosition();
Log.i("dx", String.valueOf(dx));
Log.i("dy", String.valueOf(dy));
Log.i("visibleItemCount", String.valueOf(visibleItemCount));
Log.i("firstVisibleItem", String.valueOf(firstVisibleItem));
Log.i("totalItemCount", String.valueOf(totalItemCount));
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
loading = true;
getMoreTracks(1, 2);
}
}
});
//
// nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
// #Override
// public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
// if (!loading && v.getChildAt(v.getChildCount() - 1) != null) {
// if ((scrollY >= (v.getChildAt(v.getChildCount() - 1).getMeasuredHeight() - v.getMeasuredHeight())) &&
// scrollY > oldScrollY) {
// progressBar.setVisibility(View.VISIBLE);
// loading = true;
//
// getMoreTracks(scrollX, scrollY);
//
//
// }
// }
// }
// });
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
#Override
public void onBackPressed() {
mWebSocketClient.close();
super.onBackPressed();
}
}
}
Updated XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:expandedTitleGravity="bottom"
app:expandedTitleMarginStart="#dimen/activity_vertical_margin"
app:expandedTitleTextAppearance="#style/CollapsedAppBarTopic"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="parallax">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/activity_vertical_margin">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:alpha="0.5"
app:layout_collapseMode="parallax"
app:srcCompat="#drawable/logo_white" />
<TextView
android:id="#+id/yourVotes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_toLeftOf="#+id/votesSum"
android:layout_toStartOf="#+id/votesSum"
android:text="#string/YourVotes"
android:textAlignment="viewStart" />
<TextView
android:id="#+id/votesSum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:text="1" />
</RelativeLayout>
</FrameLayout>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbarDetails"
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/tracks_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp"
android:background="#color/colorBackground"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/colorPrimary"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#drawable/bottom_nav_colors"
app:itemTextColor="#drawable/bottom_nav_colors"
app:menu="#menu/navigation" />
</android.support.design.widget.CoordinatorLayout>
All you have to do is use below line in your activity class:
ViewCompat.setNestedScrollingEnabled(recycler_view, false);
its compatible for lower versions also. and if you want to give compatible to API >21 only then use;
recycler_view.setNestedScrollingEnabled(false);
Since your final objective is to have the ToolBar diasappear/collapse when you scroll on the recyclerView, you should not use NestedScrollView, but CoordinatorLayout instead.
Have a look here.
Here is a quick example taken from the doc I provided on how to create a collapsing toolbar.
Firstly in your xml:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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: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_scrollFlags="scroll|enterAlways"></android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
Make sure that in your Activity, in your onCreate() you set it the right way:
CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("Title");
Hope it helps.

How using Coordinator Layout load from Detail activity

i have a problem with my Coordinator layout xml, it takes from detail activity class. I don't know if click the item of RecyclerView and then my app force close.. Please tell me what is wrong with my class and my xml.
here the code of detail class
public class DetailActivity extends AppCompatActivity {
private CoordinatorLayout coordinatorLayout;
private CollapsingToolbarLayout collapsingToolbarLayout;
private Toolbar toolbar;
TextView nameTxt,propTxt,descTxt;
ImageView img;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Intent i=this.getIntent();
String name=i.getExtras().getString("NAME_KEY");
String propellant=i.getExtras().getString("PROPELLANT_KEY");
String desc=i.getExtras().getString("DESCRIPTION_KEY");
String imageurl=i.getExtras().getString("IMAGEURL_KEY");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
initToolbar();
coordinatorLayout =(CoordinatorLayout) findViewById(R.id.coordinator);
collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.maincollapsing);
collapsingToolbarLayout.setTitle("NAME_KEY");
nameTxt= (TextView) findViewById(R.id.nameTxtDetail);
propTxt= (TextView) findViewById(R.id.propellantTxtDetail);
descTxt= (TextView) findViewById(R.id.descDetailTxt);
img= (ImageView) findViewById(R.id.mainbackdrop);
nameTxt.setText(name);
propTxt.setText(propellant);
descTxt.setText(Html.fromHtml(desc));
PicassoClient.downloadImage(this,imageurl,img);
}
private void initToolbar(){
toolbar = (Toolbar) findViewById(R.id.maintoolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sample_actions, menu);
return true;
}
}
and this my xml code :
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/coordinator"
android:background="#android:color/background_light"
tools:context="com.tutorials.hp.ditkeu.m_DetailActivity.DetailActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/mainappbar"
android:layout_width="match_parent"
android:layout_height="300dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/maincollapsing"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="48dp"
app:expandedTitleMarginStart="10dp"
android:fitsSystemWindows="true"
app:expandedTitleMarginBottom="16dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleTextAppearance="#style/CollapsedAppBarTopic">
<ImageView
android:id="#+id/mainbackdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/placeholder"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="#+id/maintoolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">
<LinearLayout
style="#style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/nameTxtDetail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:textStyle="bold"
android:layout_alignParentStart="true"
android:paddingLeft="5dp"
android:text="Judul Berita"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/input_register_bg" />
<TextView
android:id="#+id/propellantTxtDetail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:padding="5dp"
android:text="Tanggal "
android:textAppearance="? android:attr/textAppearanceSmall"
android:textColor="#color/input_register_bg" />
<TextView
android:id="#+id/descDetailTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Isinya... "
android:textColor="#color/input_login"
android:paddingLeft="5dp"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
one of the reasons you are calling
setSupportActionBar(toolbar);
before
initToolbar();
Actually u are calling setSupportActionBar(toolbar) twice in onCreate and in initToolbar() Do thisremove setSupportActionBar(toolbar) and getSupportActionBar().setDisplayHomeAsUpEnabled(true) from onCreate

Using a coordinatorlayout to collapse a full screen imageview and replace it with viewpager with headers

I started playing around with coordinatoralyout and I'm trying to achieve the behavior on the attached image, I want a background image to be on full screen size and upon a scroll I want some textviews to dissapear and some to stick as parts of a viewpager (rather then a toolbarlayout) any guidance on how can I achieve this?
You can use layout_behavior to handle the strings which you want to be disappear upon scroll. Customise your view behaviour using CoordinatorLayout.Behavior
ViewBehavior.java
public class ViewBehavior extends CoordinatorLayout.Behavior<RelativeLayout> {
private Context mContext;
public ViewBehavior(Context context, AttributeSet attrs) {
mContext = context;
}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, RelativeLayout child, View dependency) {
return dependency instanceof AppBarLayout;
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, RelativeLayout child, View dependency) {
child.measure(View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.AT_MOST));
int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange();
float percentage = Math.abs(dependency.getY()) / (float) maxScroll;
float childPosition = dependency.getHeight()
+ dependency.getY()
- child.getMeasuredHeight()
- (getToolbarHeight() - child.getMeasuredHeight()) * percentage / 2;
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
child.setLayoutParams(lp);
child.setY(childPosition);
return true;
}
public int getToolbarHeight() {
int result = 0;
TypedValue tv = new TypedValue();
if (mContext.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
result = TypedValue.complexToDimensionPixelSize(tv.data, mContext.getResources().getDisplayMetrics());
}
return result;
}
}
In layout xml, set your custom view behaviour as a app:layout_behavior in the view you want to handle.
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"
android:id="#+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
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:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="#+id/llViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
android:textColor="#color/red"
app:pstsShouldExpand="true"
app:pstsTextAllCaps="true" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.stacktest.ViewBehavior">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="36dp"
android:layout_marginTop="20dp"
android:text="Text-1" />
<TextView
android:id="#+id/txt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginBottom="20dp"
android:layout_marginRight="36dp"
android:layout_marginTop="20dp"
android:text="Text-2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#id/txt2"
android:layout_marginBottom="20dp"
android:layout_marginLeft="36dp"
android:paddingRight="20dp"
android:text="Text-3" />
<TextView
android:id="#+id/txt4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/txt2"
android:layout_marginBottom="20dp"
android:layout_marginRight="36dp"
android:text="Text-4" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Finally, use the layout and create ViewPager and Tabs in your Activity class.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar)).setTitle(" ");
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
PagerSlidingTabStrip tabsStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs);
tabsStrip.setViewPager(viewPager);
}
public class MyPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private String tabTitles[] = new String[] { "Tab1", "Tab2" };
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
return TestFragment.newInstance(position + 1);
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
}
}
Add following extra dependency in build.gradle along with appcompat and support library.
com.android.support:design:23.2.1
com.astuetz:pagerslidingtabstrip:1.0.1 (for ViewPager tabs)
As I am not sure if you want a particular or a general solution, I am going to give you my solution for your particular question. The key is to work with scrollFlags and collapseMode. If you really want to hide the tabs when the appBar is expanded, you can play with visibility.
<?xml version="1.0" encoding="utf-8"?>
<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.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|snap">
<RelativeLayout
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="375dp"
android:src="#drawable/ic_launcher"/>
<LinearLayout
android:layout_marginBottom="30dp"
android:layout_below="#+id/image"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView
android:layout_marginLeft="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="textView1"/>
<TextView
android:layout_marginLeft="140dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="textView2"/>
</LinearLayout>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/mToolbar"
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>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView
android:layout_marginLeft="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="textView3"/>
<TextView
android:layout_marginLeft="140dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="textView4"/>
</LinearLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
android:background="?attr/colorPrimary"
app:tabMode="scrollable"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/tab_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />

CollapsingToolbarLayout with 2 pin layout

I write this code but not works properly. I want the imageview collapse in parallax mode, and toolbar and relative layout pin at top of the screen. they pin and don't scroll but the relative layout cover on the toolbar. I want relative layout stay bottom of toolbar and don't scroll.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.CoordinatorLayout
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.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="250dp"
android:text="New Button"
android:id="#+id/button" />
<Button
android:layout_width="wrap_content"
android:layout_height="250dp"
android:text="New Button"
android:id="#+id/button2" />
<Button
android:layout_width="wrap_content"
android:layout_height="250dp"
android:text="New Button"
android:id="#+id/button3" />
<Button
android:layout_width="wrap_content"
android:layout_height="250dp"
android:text="New Button"
android:id="#+id/button4" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/appBar"
android:background="#44C8F5">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/CollapsingToolbarLayout"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/header_image"
android:src="#drawable/header_test"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:layout_collapseMode="parallax"
android:scaleType="fitXY"
android:adjustViewBounds="true"/>
<android.support.v7.widget.Toolbar
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:id="#+id/toolbar"
app:layout_scrollFlags="enterAlways"
app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/footer_appbar_padding"
app:layout_scrollFlags="enterAlways"
android:focusableInTouchMode="false">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right|center_vertical">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/textView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/textView2" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView2"
android:src="#drawable/faranesh_logo"
android:layout_gravity="right|center_vertical" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button5"
android:layout_gravity="left|center_vertical" />
</FrameLayout>
</RelativeLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
public class MainActivity extends AppCompatActivity {
private CollapsingToolbarLayout collapsingToolbar;
private ImageView headerImage;
private Toolbar toolbar;
private Drawer result;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(R.string.drawer_item_custom_container_drawer);
getSupportActionBar().setDisplayShowTitleEnabled(false);
AppBarLayout.OnOffsetChangedListener mListener = new AppBarLayout.OnOffsetChangedListener() {
#SuppressLint("NewApi")
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
headerImage.setImageAlpha((int)( 255*(((double)(headerImage.getHeight()+verticalOffset)/headerImage.getHeight()))));
}
};
((AppBarLayout) findViewById(R.id.appBar)).addOnOffsetChangedListener(mListener);
}
#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_main, 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);
}
}

How to do Collapsing ToolBar Layout collapses with a button click?

I don't know if it's possible control when it collapses. Or if an effect similar can be done with an ImageView. I would like to do an effect similar to the app Yummly
AppBarLayout has two methods that let you control the collapsing of the CollapsingToolbarLayout: setExpanded(expanded, animate) and setExpanded(expanded). Call one of them inside your OnClickListener.
Expand/Collapse Toolbar with a FloatingActionButton click using CoordinatorLayout, AppBarLayout, setExpanded(boolean expanded) (Support Library v23+)
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!--This view depends heavily on being used as a direct child within a CoordinatorLayout-->
<android.support.design.widget.AppBarLayout
android:id="#+id/appbarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" >
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#b71c1c"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:minHeight="96dp"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Expandable/Collapsible Toolbar" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="#+id/v2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="24dp"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Content" />
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:src="#drawable/ic_add_white_24px"
app:layout_anchor="#id/v2"
app:layout_anchorGravity="top|right|end"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
appBarLayout.setExpanded(true/false)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final AppBarLayout appbarLayout = (AppBarLayout)findViewById(R.id.appbarLayout);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (appbarLayout.getTop() < 0)
appbarLayout.setExpanded(true);
else
appbarLayout.setExpanded(false);
}
});
}
Image: Expand/Collapse Toolbar with FAB click

Categories

Resources