Question

Hey, I didn't like the Android's TimePicker (it's very big) so I created one by myself, but everytime I try to add it, it just crashes my app. I tried to add a TimePicker in the same way and it's working. this is the code, 3 classes, the inside class create the digits scroller, the second class create a time picker with two digits scrollers, one for the hours and one for the minutes. the third class is for the app, and create a set of two time pickers one for the open time, and one for the close time.

public class openCloseTimesPicker extends 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;
            }
        }
    }
}

This is the code to add the view to the layout:

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

I'll say it again, when I'm trying somehing like this, it's working:

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

This is the log using 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

Thanks, Elad!

Was it helpful?

Solution

In your openCloseTimesPicker constructor. It seems closeTimePicker and openTimePicker are uninitialized.

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

OTHER TIPS

Nowhere in the code you posted do you actually create openTimePicker and closeTimePicker. I see the variable declarations, but no calls to create instances.

Without creating them your call to

addView(closeTimePicker);

is just passing null to addView

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top