Java Android:在自定义视图中设置子视图的背景
所以我在自定义视图中遇到了这个问题。我正在尝试创建一个带有无限滚动动画的自定义Java Android:在自定义视图中设置子视图的背景,java,android,overriding,android-custom-view,custom-view,Java,Android,Overriding,Android Custom View,Custom View,所以我在自定义视图中遇到了这个问题。我正在尝试创建一个带有无限滚动动画的自定义RelativeLayout。为此,我创建了一个布局backgroundscrollrelativelayout.xml,如下所示: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent"
RelativeLayout
。为此,我创建了一个布局backgroundscrollrelativelayout.xml
,如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainTile"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/topTile" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/leftTile" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/diagonalTile" />
</RelativeLayout>
public class BackgroundScrollRelativeLayout extends RelativeLayout {
final int layoutToUse = R.layout.backgroundscrollrelativelayout;
final int mainTileId = R.id.mainTile;
final int leftTileId = R.id.leftTile;
final int topTileId = R.id.topTile;
final int diagonalTileId = R.id.diagonalTile;
final float valueStart = 0.0f;
final float valueEnd = 1.0f;
final long animationDuration = 50000L;
private Context mContext;
private ValueAnimator scrollAnimator;
private ImageView mainTile;
private ImageView leftTile;
private ImageView topTile;
private ImageView diagonalTile;
public BackgroundScrollRelativeLayout(Context context) {
super(context);
mContext = context;
acquireViewsInLayout();
initializeAnimator();
scrollAnimator.start();
}
public BackgroundScrollRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
acquireViewsInLayout();
initializeAnimator();
scrollAnimator.start();
}
public BackgroundScrollRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
acquireViewsInLayout();
initializeAnimator();
scrollAnimator.start();
}
@Override
public void setBackgroundColor(int color) {
// Not supported
}
@Override
public void setBackgroundResource(int resid) {
// Not supported
}
@Override
public void setBackground(Drawable background) {
mainTile.setBackground(background);
leftTile.setBackground(background);
}
/*
@Override
public void setBackgroundDrawable(Drawable background) {
//super.setBackgroundDrawable(background);
//mainTile.setBackground(background);
//leftTile.setBackground(background);
}*/
// Intent: Inflate the layout associated with this View
private void inflateLayout(){
// TO inflateLayout, we connect the inflater to context, then we call inflate the layout associated
// with this view
//LayoutInflater inflater = LayoutInflater.from(mContext);
//inflater.inflate(layoutToUse, this);
inflate(getContext(), layoutToUse, this);
}
// Intent: Find all Views in Layout
private void findAllViewsById(){
mainTile = (ImageView)this.findViewById(mainTileId);
leftTile = (ImageView)this.findViewById(leftTileId);
topTile = (ImageView)this.findViewById(topTileId);
diagonalTile = (ImageView)this.findViewById(diagonalTileId);
}
// Intent: Concretely acquire all Views in Layout
private void acquireViewsInLayout(){
// TO acquireViewsInLayout, we inflate the layout,
// then we find the view of each known view id and save the view
inflateLayout();
findAllViewsById();
}
// Intent: Initialize animator properties
private void initializeAnimator(){
// TO initializeAnimator, we set how the animator will keep track of animation,
// then we set the animation repeat type, then we set the type of interpolation,
// then we set the animation duration, then we apply animation update listener
scrollAnimator = ValueAnimator.ofFloat(valueStart, valueEnd);
scrollAnimator.setRepeatCount(ValueAnimator.INFINITE);
scrollAnimator.setInterpolator(new LinearInterpolator());
scrollAnimator.setDuration(animationDuration);
addScrollAnimatorUpdateListener();
}
// Intent: Add an update listener to the scroll animator
private void addScrollAnimatorUpdateListener(){
// TO addScrollAnimatorUpdateListener, we add an update listener to scroll animator
scrollAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Do something...
updateScrollAnimation();
}
});
}
private void updateScrollAnimation(){
float progress = (float)scrollAnimator.getAnimatedValue();
float widthOfTile = mainTile.getWidth();
float moveInXAxis = widthOfTile * progress;
mainTile.setTranslationX(moveInXAxis);
leftTile.setTranslationX(moveInXAxis - widthOfTile);
// Ignore the rest for now
topTile.setTranslationY(-1.0f);
diagonalTile.setTranslationX(-1.0f);
diagonalTile.setTranslationY(-1.0f);
}
}
我在活动中使用自定义视图:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.martianstudio.adivinaque.AppSettingsActivity">
<com.martianstudio.adivinaque.BackgroundScrollRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/main_activity_animation_icon" />
</RelativeLayout>
但是,我得到了这个错误:
java.lang.NullPointerException at com.martianstudio.adivinaque.BackgroundScrollRelativeLayout.setBackground
这表示未设置setBackground
中的mainTile
(为空)。在我的findAllViewsById()
中,我显式地编写this.mainTile=(ImageView)this.findViewById(mainTileId)代码>,其中mainTileId=R.id.mainTile
,我在inflateLayout()中充气布局。这两个方法都在类的构造函数中调用。在我看来,由于某种原因,当我像我一样重写setBackground
方法时,它无法找到带有mainTile
Id的ImageView
。如果我不重写setBackground
方法,我不会得到NullPointerException,但是,它默认为默认的setBackground方法,这是我不想要的。我错过什么了吗
任何帮助都将不胜感激:)。谢谢大家! 也许它是这样工作的:inflateLayout()
中的这个是包含customView的rooView。rootView不包含ImageView mainTile、leftTile..等。因此,如果您使用this
来findViewById
将返回null
@hoangngnguyen,我稍后在updateScrollAnimation函数中有mainTile.setTranslationX(moveInAxis),它不会抱怨空指针。我认为当Android系统调用setBackground()时,它会在膨胀布局之前进行调用,以便findViewById返回null。我想我必须通过ATTR获得可提取资源。如果我找到什么,我会再查。谢谢你的评论!也许它是这样工作的:inflateLayout()
中的这个是包含customView的rooView。rootView不包含ImageView mainTile、leftTile..等。因此,如果您使用this
来findViewById
将返回null
@hoangngnguyen,我稍后在updateScrollAnimation函数中有mainTile.setTranslationX(moveInAxis),它不会抱怨空指针。我认为当Android系统调用setBackground()时,它会在膨胀布局之前进行调用,以便findViewById返回null。我想我必须通过ATTR获得可提取资源。如果我找到什么,我会再查。谢谢你的评论!
java.lang.NullPointerException at com.martianstudio.adivinaque.BackgroundScrollRelativeLayout.setBackground