尝试以编程方式添加视图时,应用程序崩溃

时间:2011-05-14 16:59:44

标签: android xml view android-custom-view

嘿,我不喜欢Android的TimePicker(它非常大)所以我自己创建了一个,但每次我尝试添加它时,它都会崩溃我的应用程序。我尝试以相同的方式添加TimePicker并且它正在工作。 这是代码,3个类,内部类创建数字滚动条,第二个类创建一个带有两个数字滚动条的时间选择器,一个用于小时,一个用于分钟。第三个类是针对应用程序,并为开放时间创建一组两个时间选择器,并为关闭时间创建一个。

公共类openCloseTimesPicker扩展LinearLayout {         private smallTimePicker openTimePicker;         private smallTimePicker closeTimePicker;

    public openCloseTimesPicker(Context context) {
        super(context);

        setOrientation(HORIZONTAL);

        setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

        TextView from = new TextView(context);
        TextView until = new TextView(context);

        from.setGravity(Gravity.CENTER_VERTICAL);
        from.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        from.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 25.0f);
        from.setText("מ:");

        until.setGravity(Gravity.CENTER_VERTICAL);
        until.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        until.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 25.0f);
        until.setText("עד:");

        addView(closeTimePicker);
        addView(until);
        addView(openTimePicker);
        addView(from);
    }
    public String getOpenHour(){
        return openTimePicker.getHour();
    }
    public String getCloseHour(){
        return closeTimePicker.getHour();
    }
    private class smallTimePicker extends LinearLayout{
        private digitsScroller minutes;
        private digitsScroller hours;

        public smallTimePicker(Context context) {
            super(context);
            minutes = new digitsScroller(context, 0, 59);
            hours = new digitsScroller(context, 0, 23);

            setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

            setGravity(Gravity.CENTER_HORIZONTAL);

            // Stacks elements vertically
            setOrientation(HORIZONTAL);

            TextView colon = new TextView(context);
            colon.setGravity(Gravity.CENTER_VERTICAL);
            colon.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            colon.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 25.0f);
            colon.setText(':');

            addView(hours);
            addView(colon);
            addView(minutes);

        }
        public String getHour(){
            return hours.getDigits() + ':' + minutes.getDigits();
        }
        private class digitsScroller extends LinearLayout{

            private ImageView increase;
            private ImageView decrease;
            private TextView digitDisplay;
            private int minimum, maximum;

            public digitsScroller(Context context, int minimum, int maximum) {
                super(context);

                this.minimum = minimum;
                this.maximum = maximum;

                setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

                setGravity(Gravity.CENTER_HORIZONTAL);

                // Stacks elements vertically
                setOrientation(VERTICAL);

                initializeViews(context);

                addView(increase);
                addView(digitDisplay);
                addView(decrease);
            }
            private void initializeViews(Context context) {
                // Layout settings
                LayoutParams childParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

                // Setting the increase button
                increase = new ImageView(context);
                increase.setLayoutParams(childParams);
                increase.setImageResource(R.drawable.add_increase);
                increase.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Evaluate whether the digit display may be increased further
                        int currentValue = Integer.valueOf(digitDisplay.getText().toString());
                        currentValue = currentValue < maximum ? currentValue + 1 : minimum;

                        updateDigitValue(currentValue);
                    }
                });

                // Setting the decrease button
                decrease = new ImageView(context);
                decrease.setLayoutParams(childParams);
                decrease.setImageResource(R.drawable.add_decrease);
                decrease.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Evaluate whether the digit display may be increased further
                        int currentValue = Integer.valueOf(digitDisplay.getText().toString());
                        currentValue = currentValue > minimum ? currentValue - 1 : maximum;

                        updateDigitValue(currentValue);
                    }
                });

                // Setting the digits display
                digitDisplay = new TextView(context);
                digitDisplay.setGravity(Gravity.CENTER_HORIZONTAL);
                digitDisplay.setLayoutParams(childParams);
                digitDisplay.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 25.0f);
                digitDisplay.setText('0'+minimum);
            }
            private void updateDigitValue(int newValue) {
                digitDisplay.setText((newValue > 9) ? Integer.toString(newValue) : '0'+ Integer.toString(newValue));
                digitDisplay.postInvalidate();
            }
            public String getDigits(){
                String digits = digitDisplay.getText().toString();
                return (digits.length()>1) ? digits : '0'+digits;
            }
        }
    }
}

这是将视图添加到布局的代码:

    else if(v.getId() == R.id.add_open_time){
        table.addView(new openCloseTimesPicker(AddShopActivity.this));
    }

我会再次这样说,当我尝试这样的事情时,它正在发挥作用:

    else if(v.getId() == R.id.add_open_time){
        table.addView(new TimePicker(AddShopActivity.this));
    }

这是使用adb logcat的日志:

D/AndroidRuntime(  227): Shutting down VM
W/dalvikvm(  227): threadid=3: thread exiting with uncaught exception (group=0x4
001aa28)
E/AndroidRuntime(  227): Uncaught handler: thread main exiting due to uncaught e
xception
E/AndroidRuntime(  227): java.lang.NullPointerException
E/AndroidRuntime(  227):        at android.view.ViewGroup.addView(ViewGroup.java
:1701)
E/AndroidRuntime(  227):        at android.view.ViewGroup.addView(ViewGroup.java
:1688)
E/AndroidRuntime(  227):        at elad.openapp.AddShopActivity$openCloseTimesPi
cker.<init>(AddShopActivity.java:99)
E/AndroidRuntime(  227):        at elad.openapp.AddShopActivity.onClick(AddShopA
ctivity.java:72)
E/AndroidRuntime(  227):        at android.view.View.performClick(View.java:2344
)
E/AndroidRuntime(  227):        at android.view.View.onTouchEvent(View.java:4133
)
E/AndroidRuntime(  227):        at android.widget.TextView.onTouchEvent(TextView
.java:6510)
E/AndroidRuntime(  227):        at android.view.View.dispatchTouchEvent(View.jav
a:3672)
E/AndroidRuntime(  227):        at android.view.ViewGroup.dispatchTouchEvent(Vie
wGroup.java:882)
E/AndroidRuntime(  227):        at android.view.ViewGroup.dispatchTouchEvent(Vie
wGroup.java:882)
E/AndroidRuntime(  227):        at android.view.ViewGroup.dispatchTouchEvent(Vie
wGroup.java:882)
E/AndroidRuntime(  227):        at android.view.ViewGroup.dispatchTouchEvent(Vie
wGroup.java:882)
E/AndroidRuntime(  227):        at com.android.internal.policy.impl.PhoneWindow$
DecorView.superDispatchTouchEvent(PhoneWindow.java:1712)
E/AndroidRuntime(  227):        at com.android.internal.policy.impl.PhoneWindow.
superDispatchTouchEvent(PhoneWindow.java:1202)
E/AndroidRuntime(  227):        at android.app.Activity.dispatchTouchEvent(Activ
ity.java:1987)
E/AndroidRuntime(  227):        at com.android.internal.policy.impl.PhoneWindow$
DecorView.dispatchTouchEvent(PhoneWindow.java:1696)
E/AndroidRuntime(  227):        at android.view.ViewRoot.handleMessage(ViewRoot.
java:1658)
E/AndroidRuntime(  227):        at android.os.Handler.dispatchMessage(Handler.ja
va:99)
E/AndroidRuntime(  227):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(  227):        at android.app.ActivityThread.main(ActivityThrea
d.java:4203)
E/AndroidRuntime(  227):        at java.lang.reflect.Method.invokeNative(Native
Method)
E/AndroidRuntime(  227):        at java.lang.reflect.Method.invoke(Method.java:5
21)
E/AndroidRuntime(  227):        at com.android.internal.os.ZygoteInit$MethodAndA
rgsCaller.run(ZygoteInit.java:791)
E/AndroidRuntime(  227):        at com.android.internal.os.ZygoteInit.main(Zygot
eInit.java:549)
E/AndroidRuntime(  227):        at dalvik.system.NativeStart.main(Native Method)

I/Process (   44): Sending signal. PID: 227 SIG: 3
I/dalvikvm(  227): threadid=7: reacting to signal 3
E/dalvikvm(  227): Unable to open stack trace file '/data/anr/traces.txt': Permi
ssion denied

谢谢,很高兴!

2 个答案:

答案 0 :(得分:0)

openCloseTimesPicker构造函数中。似乎closeTimePickeropenTimePicker未初始化。

    addView(closeTimePicker);
    addView(until);
    addView(openTimePicker);
    addView(from);

答案 1 :(得分:0)

您发布的代码中没有任何地方您实际创建了openTimePicker和closeTimePicker。我看到变量声明,但没有调用创建实例。

无需创建对

的调用
addView(closeTimePicker);

只是将null传递给addView