【问题标题】:Add custom view as a view of XML layout添加自定义视图作为 XML 布局的视图
【发布时间】:2011-11-02 13:14:10
【问题描述】:

场景如下:

我有一个活动 RunTrainingWorkoutsView,它使用 XML 布局 _run_workout.xml_ 和一些由 CountDownTimer 更新的标签。工作正常...

现在,除了由 CountDownTimer 对象的 onTick() 回调方法每秒更新的标签之外,我想在我的 _run_workout.xml 布局中添加一个自定义表面视图,该视图将绘制一些由每秒相同的 onTick() 方法...

我的 run_workout.xml:

<training.timer.CounterClockView 
    android:id="@+id/counter_clock_surface"
    android:layout_width="300dp" 
    android:layout_height="240dp">
</training.timer.CounterClockView>

我的自定义视图扩展了 surfaceView

public class CounterClockView extends SurfaceView {

Paint paint = new Paint();
Paint paint2 = new Paint();

final RectF rect = new RectF();
final RectF rect2 = new RectF();

int counterArcAngle = 15;
//constructor
public CounterClockView(Context context, AttributeSet attributeSet) {
    super(context);

    //setting some paint properties...

    this.setBackgroundColor(Color.TRANSPARENT);

}

@Override
public void onDraw(Canvas canvas) {

    rect.set(50, 50, 150, 150);
    rect2.set(50, 50, 150, 150);

    this.layout(0, 0, 200, 200);

    canvas.drawArc(rect, -90, 360, false, paint);
    canvas.drawArc(rect2, -90, counterArcAngle, false, paint2);

}

我的扩展活动的主要类正在使用以下代码在布局中获取对自定义 surfaceView 的引用:

//counterClockView  is declared outside of onCreate() as CounterClockView counterClockView;  

//later in onCreate(){....
counterClockView  = (CounterClockView) findViewById(R.id.counter_clock_surface);

问题是修改customView对象(counterClockView)的成员变量的值

counterClockView.counterArcAngle = 10;

会使应用程序崩溃...

另外,在我的主要活动中,我想在更改 counterArcAngle 值后调用 invalidate() 方法来重做表面视图,但这也会导致应用程序崩溃...

为什么不能创建 counterClockView 对象并将其引用到相同类型的 xml 布局元素并更改其外观、使其无效等?

编辑 LogCat

threadid=1: thread exiting with uncaught exception (group=0x40015560)

ERROR/AndroidRuntime(487): FATAL EXCEPTION: main

ERROR/AndroidRuntime(487): java.lang.RuntimeException: Unable to start activity ComponentInfo{training.timer/training.timer.RunTrainingWorkoutsView}: java.lang.NullPointerException

ERROR/AndroidRuntime(487):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
ERROR/AndroidRuntime(487):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
ERROR/AndroidRuntime(487):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
ERROR/AndroidRuntime(487):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
ERROR/AndroidRuntime(487):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(487):     at android.os.Looper.loop(Looper.java:123)

ERROR/AndroidRuntime(487):     at android.app.ActivityThread.main(ActivityThread.java:3683)
ERROR/AndroidRuntime(487):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(487):     at java.lang.reflect.Method.invoke(Method.java:507)
ERROR/AndroidRuntime(487):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
ERROR/AndroidRuntime(487):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
ERROR/AndroidRuntime(487):     at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(487): Caused by: java.lang.NullPointerException
ERROR/AndroidRuntime(487):     at training.timer.RunTrainingWorkoutsView.onCreate(RunTrainingWorkoutsView.java:72)
ERROR/AndroidRuntime(487):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
ERROR/AndroidRuntime(487):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
ERROR/AndroidRuntime(487):     ... 11 more

【问题讨论】:

  • 错误日志是什么?从LogCat读取输出
  • RunTrainingWorkoutsView.onCreate() 在此方法中,此文件中的第 72 行 RunTrainingWorkoutsView.java,一个对象是 NULL。看看吧!
  • 嗯,这就是问题...如果我有:TextView txt = (TextView) findViewById(...) 它不会是 NULL 所以问题是为什么我的自定义视图(surfaceView ) 空???

标签: android android-layout surfaceview


【解决方案1】:

我在用头撞墙 3 天后通过谷歌搜索、stacOverflowing 等获得了它。

其实就是这个傻小子……

我的 XML 文件在其中定义了包含一些常用的 android 视图(即 textView 和按钮)和我的自定义视图 CounterClockView 的布局:

<training.timer.CounterClockView 
android:id="@+id/counter_clock_surface"
android:layout_width="300dp" 
android:layout_height="240dp">

我不得不多加一行!

<training.timer.CounterClockView 
    xmlns:android="http://schemas.android.com/apk/res/android"   !!!
    android:id="@+id/counter_clock_surface"
    android:layout_width="300dp" 
    android:layout_height="240dp">
</training.timer.CounterClockView>

我不知道为什么这个命名空间行会产生如此巨大的差异,但它的效果很好!

现在,我可以从 CountDownTimer() 的每个 onTick() 的主要活动中更新我的自定义视图...

以下答案非常有帮助: findViewById() returns null for custom component in layout XML, not for other components

【讨论】:

    【解决方案2】:

    有同样的问题,所以我只是在我的自定义视图的 Java 类中实现了所有三个构造函数,所有三个构造函数加上 onDrow 方法,它就像一个魅力。试试看。

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class CustomWorldWideView extends View {
    
        public CustomWorldWideView(Context context) {
    
            super(context);
        }
    
        public CustomWorldWideView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomWorldWideView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            //Some simple draw on the view...
            Paint paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(Color.parseColor("#FFA800"));
    
    
            Path path = new Path();
    
            path.moveTo(0, 0);
            path.lineTo(getWidth() / 2, 0);
            path.lineTo(getWidth(), getHeight()/2);
            path.lineTo(getWidth() / 2, getHeight());
            path.lineTo( 0, getHeight());
            path.lineTo( 0, 0);
    
            canvas.drawPath(path, paint);
    
    
        }
    }
    

    XML:

            <PackageName.CustomWorldWideView
                android:layout_width="56.00dp"
                android:layout_height="43dp"
                android:id="@+id/world_wide_grid_view_2"
                />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 2013-03-29
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多