尝试设置 CollapsingToolbarLayout 的副标题时获取 'java.lang.ClassCastException'
Getting 'java.lang.ClassCastException' while trying to set subtitle of a CollapsingToolbarLayout
我正在尝试在我的应用程序中使用此 example 设置 'Sub-title' 的 CollapsingToolbarLayout
。
这是 Profile.java
的 onCreate()
中的代码:
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");
这是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>
这是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>
这是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);
}
}
这里是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;
}
}
问题 是我收到此错误: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
在上面指定的行上。
为什么我 收到此错误以及如何 解决它?
请告诉我。
你没有在你的代码中显示,但我敢打赌你的 header_view.xml
有一个 LinearLayout
作为根视图。
所以基本上发生的事情是:header_view.xml
根部的 LinearLayout
的 <include
代码 "gets replaced" 然后你调用 findViewById(R.id.toolbar_header_view)
returns LinearLayout
然后用 (HeaderView)
你告诉虚拟机这是一个 HeaderView,但它是一个 LinearLayout。所以它崩溃了!
没有看到您未显示的代码片段的最佳选择是以下之一:
- 将
<HeaderView>
放在header_view.xml
, 的根部
或者如果那是不可能的,因为里面有更多的东西header_view.xml
- 更改您的代码以找到
include
然后在 include 中找到实际的 HeaderView。
类似于:
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);
请注意,它会调用 findViewById
两次。一个用于包含,另一个用于其中的 HeaderView
我正在尝试在我的应用程序中使用此 example 设置 'Sub-title' 的 CollapsingToolbarLayout
。
这是 Profile.java
的 onCreate()
中的代码:
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");
这是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>
这是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>
这是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);
}
}
这里是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;
}
}
问题 是我收到此错误: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
在上面指定的行上。
为什么我 收到此错误以及如何 解决它?
请告诉我。
你没有在你的代码中显示,但我敢打赌你的 header_view.xml
有一个 LinearLayout
作为根视图。
所以基本上发生的事情是:header_view.xml
根部的 LinearLayout
的 <include
代码 "gets replaced" 然后你调用 findViewById(R.id.toolbar_header_view)
returns LinearLayout
然后用 (HeaderView)
你告诉虚拟机这是一个 HeaderView,但它是一个 LinearLayout。所以它崩溃了!
没有看到您未显示的代码片段的最佳选择是以下之一:
- 将
<HeaderView>
放在header_view.xml
, 的根部
或者如果那是不可能的,因为里面有更多的东西header_view.xml
- 更改您的代码以找到
include
然后在 include 中找到实际的 HeaderView。
类似于:
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);
请注意,它会调用 findViewById
两次。一个用于包含,另一个用于其中的 HeaderView