69075

Getting 'java.lang.ClassCastException' while trying to set subtitle of a CollapsingToolbar

Question:

I'm trying to set 'Sub-title' of a CollapsingToolbarLayout in my app using this <a href="https://github.com/harcoPro/SubtitleCoordinatorLayoutExample" rel="nofollow">example</a> here.

Here's the code from onCreate() of Profile.java:

CollapsingToolbarLayout collapsingToolbarLayout; Toolbar toolbar; HeaderView toolbarHeaderView; HeaderView floatHeaderView; collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapse_toolbar); // error on the line below toolbarHeaderView = (HeaderView) findViewById(R.id.toolbar_header_view); floatHeaderView = (HeaderView) findViewById(R.id.float_header_view); toolbarHeaderView.bindTo("title", "subtitle"); floatHeaderView.bindTo("title", "subtitle");

Here's activity_main.xml:

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout android:id="@+id/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.abc.zzz.Profile"> <android.support.design.widget.AppBarLayout android:id="@+id/appBarLayout" android:layout_width="match_parent" android:layout_height="256dp" android:theme="@style/AppTheme.AppBarOverlay" android:fitsSystemWindows="true"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapse_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:contentScrim="@color/colorPrimary" android:fitsSystemWindows="true" app:popupTheme="@style/AppTheme.PopupOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="parallax"> <include android:id="@+id/toolbar_header_view" layout="@layout/header_view" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_marginRight="@dimen/header_view_end_margin_right" android:layout_marginEnd="@dimen/header_view_end_margin_right" android:visibility="gone" /> </android.support.v7.widget.Toolbar> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <include android:id="@+id/float_header_view" layout="@layout/header_view" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="com.abc.zzz.ViewBehavior"/> </android.support.design.widget.CoordinatorLayout>

Here's header_view.xml:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Title --> <TextView android:id="@+id/header_view_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="18sp" /> <!-- Subtitle --> <TextView android:id="@+id/header_view_sub_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="16sp" /> </LinearLayout>

Here's HeaderView.java:

public class HeaderView extends LinearLayout { TextView title; TextView subTitle; public HeaderView(Context context) { super(context); } public HeaderView(Context context, AttributeSet attrs) { super(context, attrs); } public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public HeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onFinishInflate() { super.onFinishInflate(); title = (TextView) findViewById(R.id.header_view_title); subTitle = (TextView) findViewById(R.id.header_view_sub_title); } public void bindTo(String title) { bindTo(title, ""); } public void bindTo(String title, String subTitle) { hideOrSetText(this.title, title); hideOrSetText(this.subTitle, subTitle); } private void hideOrSetText(TextView tv, String text) { if (text == null || text.equals("")) tv.setVisibility(GONE); else tv.setText(text); } }

Here's ViewBehavior.java:

public class ViewBehavior extends CoordinatorLayout.Behavior<HeaderView> { private Context mContext; private int mStartMarginLeft; private int mEndMargintLeft; private int mMarginRight; private int mStartMarginBottom; private boolean isHide; public ViewBehavior(Context context, AttributeSet attrs) { mContext = context; } @Override public boolean layoutDependsOn(CoordinatorLayout parent, HeaderView child, View dependency) { return dependency instanceof AppBarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, HeaderView child, View dependency) { shouldInitProperties(child, dependency); int maxScroll = ((AppBarLayout) dependency).getTotalScrollRange(); float percentage = Math.abs(dependency.getY()) / (float) maxScroll; float childPosition = dependency.getHeight() + dependency.getY() - child.getHeight() - (getToolbarHeight() - child.getHeight()) * percentage / 2; childPosition = childPosition - mStartMarginBottom * (1f - percentage); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); lp.leftMargin = (int) (percentage * mEndMargintLeft) + mStartMarginLeft; lp.rightMargin = mMarginRight; child.setLayoutParams(lp); child.setY(childPosition); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { if (isHide && percentage < 1) { child.setVisibility(View.VISIBLE); isHide = false; } else if (!isHide && percentage == 1) { child.setVisibility(View.GONE); isHide = true; } } return true; } private void shouldInitProperties(HeaderView child, View dependency) { if (mStartMarginLeft == 0) mStartMarginLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_left); if (mEndMargintLeft == 0) mEndMargintLeft = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_left); if (mStartMarginBottom == 0) mStartMarginBottom = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_start_margin_bottom); if (mMarginRight == 0) mMarginRight = mContext.getResources().getDimensionPixelOffset(R.dimen.header_view_end_margin_right); } 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; } }

<strong>The problem</strong> is that I'm getting this error: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.abc.zzz/com.abc.zzz.Profile}: java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to com.abc.zzz.HeaderView on the line specified above.

<strong>Why am I</strong> getting this error and <strong>how to</strong> resolve it?

Please let me know.

Answer1:

You didn't show on your code but I bet that your header_view.xml have a LinearLayout as the root view.

So basically what happens is: the <include code "gets replaced" by the LinearLayout at the root of header_view.xml and then you call findViewById(R.id.toolbar_header_view) which returns that LinearLayout and then with the (HeaderView) you're telling the VM this is a HeaderView, but it's, it's a LinearLayout. So it crashes!

The best option without seeing piece of code you didn't show it is one of the following:

<ol><li>put <HeaderView> at the root of header_view.xml,</li> </ol>

or if that is not possible because there's more stuff inside header_view.xml

<ol start="2"><li>change your code to find the include and then inside the include, to find the actual HeaderView.</li> </ol>

Something like:

toolbarHeaderView = (HeaderView) findViewById(R.id.toolbar_header_view).findViewById(R.id.header_view_id); floatHeaderView = (HeaderView) findViewById(R.id.float_header_view).findViewById(R.id.header_view_id);

note that it calls findViewById two times. One for the include and another for the HeaderView inside it

Recommend

  • using Action Bar Android development
  • How can compile I `.java file` in jsp?
  • App is crashing when we upload the image from gallery?
  • java - cookie overried in multi-thread
  • SwipeRefreshLayout with NestedScrollView and LinearLayout
  • Lucene Search Syntax
  • Html-table scraping and exporting to csv: attribute error
  • How do you write to a specific line of a txt file in C?
  • How to access tap or click of an toolbar image in android xamarin forms
  • Clean way to Parse JSON object [duplicate]
  • JavaScript regular expression to validate only path params in URL
  • Raster image on world map in ggplot
  • TimeoutException exception in StackExchange Redis .NET Library
  • RecyclerView cutting off last item
  • NestedScrollView wont't scroll to the end when used with CollapsingToolbarLayout
  • How can i add the expandable list button on the right side of the navigation drawer's menu item
  • Set Custom List view inside NestedScrollView
  • Parse URL beautifulsoup
  • Cannot replacing an old fragment with new one in a tabbed activity
  • Why dynamic power consumption is always zero?
  • Using ViewPager in activity and launch app from URL inflating Exception thrown
  • Toolbar not scrolling when using collapsing toolbar effect
  • Center title on ToolBar
  • Windows Phone 8 Http request with custom header
  • Add SwipeRefreshLayout to RecyclerView when it has an empty header
  • How close toolbar Espresso
  • Collapsible Toolbar - Make Fragment Footer Always Visible in Android
  • Is it against to MVC pattern calling a view in another view with variables?
  • How can I speed up this row-by-row operation in data.table
  • Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.goog
  • How can I pass complex expression to parametrized active pattern?
  • Stalling at deallocate
  • How to use icon from font file as a drawable in Android
  • Android TabLayout on the bottom of the screen
  • Found com.google.android.gms:play-services-places:9.2.1, but version 9.0.2 is needed for the google-
  • changes in jquery 1.4.2 breaking the code?
  • jquery code not working without breakpoint
  • SAVE attribute needed for Fortran variables when only the C_LOC address is returned to a C program?
  • saving file generated by TCPDF
  • d3 v4 drag and drop with TypeScript