【问题标题】:custom TextView fires RuntimeException "Error inflating"自定义 TextView 触发 RuntimeException “错误膨胀”
【发布时间】:2014-03-31 03:07:02
【问题描述】:

我想扩展 TextView 以实现秒表功能。我遇到的问题是关于充气过程的 runtimeException。

03-30 12:57:28.749: E/AndroidRuntime(5700): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.lipsksoft.apps.anwendung.t6student/de.lipsksoft.apps.anwendung.t6student.opsActivity}:
android.view.InflateException: Binary XML file line #29: Error inflating class de.lipsksoft.apps.anwendung.t6student.TimerView.t6student.TimerView

由于这里的提示,我做了一些更改。 我的新代码:

public class Timer extends TextView{

    private Handler handler = new Handler();
    private long startTime;
    private long elapsedTime;
    private final int REFRESH_RATE = 100;
    private String hours,minutes,seconds,milliseconds;
    private long secs,mins,hrs;
    private boolean stopped = false;

    Timer(Context context){
        super(context);
    }

    Timer (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    Timer(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
    }

    public void start(){
        if(stopped){
            startTime = System.currentTimeMillis() - elapsedTime; 
        }
        else{
            startTime = System.currentTimeMillis();
        }
        handler.removeCallbacks(startTimer);
        handler.postDelayed(startTimer, 0);
    }

    public void stop(){
        handler.removeCallbacks(startTimer);
        stopped = true;
    }

    private Runnable startTimer = new Runnable() {
           public void run() {
               elapsedTime = System.currentTimeMillis() - startTime;
               updateTimer(elapsedTime);
               handler.postDelayed(this,REFRESH_RATE);
           }
        };

    private void updateTimer (float time){
        secs = (long)(time/1000);
        mins = (long)((time/1000)/60);
        hrs = (long)(((time/1000)/60)/60);

        /* Convert the seconds to String 
         * and format to ensure it has
         * a leading zero when required
         */
        secs = secs % 60;
        seconds=String.valueOf(secs);
    if(secs == 0){
        seconds = "00";
    }
    if(secs <10 && secs > 0){
        seconds = "0"+seconds;
    }

        /* Convert the minutes to String and format the String */

    mins = mins % 60;
        minutes=String.valueOf(mins);
    if(mins == 0){
        minutes = "00";
    }
    if(mins <10 && mins > 0){
        minutes = "0"+minutes;
    }

    /* Convert the hours to String and format the String */

    hours=String.valueOf(hrs);
    if(hrs == 0){
        hours = "00";
    }
    if(hrs <10 && hrs > 0){
        hours = "0"+hours;
    }

    /* Although we are not using milliseconds on the timer in this example
     * I included the code in the event that you wanted to include it on your own
     */
    milliseconds = String.valueOf((long)time);
    if(milliseconds.length()==2){
        milliseconds = "0"+milliseconds;
    }
    if(milliseconds.length()<=1){
        milliseconds = "00";
    }
        milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-2);

        /* Setting the timer text to the elapsed time */
        this.setText(minutes + ":" + seconds + "." + milliseconds);
        //activity.((TextView)findViewById(R.id.timerMs)).setText("." + milliseconds);
    }
}

XML:

 <de.lipsksoft.apps.anwendung.t6student.Timer
        android:id="@+id/timer1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TimerView" />

但我仍然得到 sam 错误。你知道出了什么问题吗?

感谢您的帮助。

【问题讨论】:

  • 发布 xml。另外,您正在从线程更新 ui。这是错误的
  • 为什么?我以为我需要这个线程来更新?
  • 因为 ui 仅从 ui 线程更新。阅读文档进程和线程
  • 但是如何实现秒表功能呢?
  • 要有一个计时器,您可以给我们CountDownTimer 或Handler。计时器在不同的线程上运行,ui 可以从 ui 线程 onyl 更新

标签: java android multithreading view


【解决方案1】:

你需要有这些构造函数

Android Custom View Constructor

public TimerView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public TimerView (Context context) {
super(context);
}
public TimerView (Context context, AttributeSet attrs) {
super(context, attrs);
}

你也有

this.setText(milliSeconds + ":" + seconds + ":" + minutes);

您不能从非 ui 线程更新 ui。

阅读

http://developer.android.com/guide/components/processes-and-threads.html

编辑:

你有什么

public class Timer extends TextView{

然后在xml中你有

<de.lipsksoft.apps.anwendung.t6student.TimerView // TimerView is not the same as Timer

编辑 2:

活动中

TimerView  tv = (TimerView) this.findViewById(R.id.timer1);
tv.start();

然后在xml中

我的包名不一样

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
<com.example.testall.TimerView
        android:id="@+id/timer1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TimerView" />
</RelativeLayout>

然后

public class TimerView extends TextView{

    private Handler handler = new Handler();
    private long startTime;
    private long elapsedTime;
    private final int REFRESH_RATE = 100;
    private String hours,minutes,seconds,milliseconds;
    private long secs,mins,hrs;
    private boolean stopped = false;

    public TimerView(Context context){
        super(context);
        //start();
    }

    public TimerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //start();
    }

    public TimerView(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
        //start();
    }

    public void start(){
        if(stopped){
            startTime = System.currentTimeMillis() - elapsedTime; 
        }
        else{
            startTime = System.currentTimeMillis();
        }
        handler.removeCallbacks(startTimer);
        handler.postDelayed(startTimer, 0);
    }

    public void stop(){
        handler.removeCallbacks(startTimer);
        stopped = true;
    }

    private Runnable startTimer = new Runnable() {
           public void run() {
               elapsedTime = System.currentTimeMillis() - startTime;
               updateTimer(elapsedTime);
               handler.postDelayed(this,REFRESH_RATE);
           }
        };

    private void updateTimer (float time){
        secs = (long)(time/1000);
        mins = (long)((time/1000)/60);
        hrs = (long)(((time/1000)/60)/60);

        /* Convert the seconds to String 
         * and format to ensure it has
         * a leading zero when required
         */
        secs = secs % 60;
        seconds=String.valueOf(secs);
    if(secs == 0){
        seconds = "00";
    }
    if(secs <10 && secs > 0){
        seconds = "0"+seconds;
    }

        /* Convert the minutes to String and format the String */

    mins = mins % 60;
        minutes=String.valueOf(mins);
    if(mins == 0){
        minutes = "00";
    }
    if(mins <10 && mins > 0){
        minutes = "0"+minutes;
    }

    /* Convert the hours to String and format the String */

    hours=String.valueOf(hrs);
    if(hrs == 0){
        hours = "00";
    }
    if(hrs <10 && hrs > 0){
        hours = "0"+hours;
    }

    /* Although we are not using milliseconds on the timer in this example
     * I included the code in the event that you wanted to include it on your own
     */
    milliseconds = String.valueOf((long)time);
    if(milliseconds.length()==2){
        milliseconds = "0"+milliseconds;
    }
    if(milliseconds.length()<=1){
        milliseconds = "00";
    }
        milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-2);

        /* Setting the timer text to the elapsed time */
        this.setText(minutes + ":" + seconds + "." + milliseconds);
        //activity.((TextView)findViewById(R.id.timerMs)).setText("." + milliseconds);
    }
}

捕捉

【讨论】:

  • 是的,对不起……那不是问题。我只是忘了更新 xml 部分。在我的实际代码中是正确的。
  • @PeterPanne 如果这没有错,那将是一个问题。并且您需要在所有构造函数中调用 start() 并将 Timer 重命名为其他名称
  • 为什么要在所有构造函数中调用 start?我从我的活动中做到这一点,因为我想对事件做出反应(按钮点击等)。我将它重命名为 NewTimer。还是一样的错误。
  • @PeterPanne 因为你不知道使用了哪个构造函数。
  • 是不是必须在activity中创建handler?
猜你喜欢
  • 2013-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多