Java 在Android上使用类(DatePicker)创建片段

Java 在Android上使用类(DatePicker)创建片段,java,android,android-layout,android-fragments,datepicker,Java,Android,Android Layout,Android Fragments,Datepicker,我试图获取我的一个片段中的日期选择器的值。我已经阅读了Android开发者指南中关于片段的文档 以下是我的片段布局: <ir.smartlab.persindatepicker.PersianDatePicker android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:i

我试图获取我的一个片段中的日期选择器的值。我已经阅读了Android开发者指南中关于片段的文档

以下是我的片段布局:

    <ir.smartlab.persindatepicker.PersianDatePicker
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        />
      <Button
      android:id="@+id/btnCheckFal"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_below="@+id/relativeLayout1"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="19dp"
      android:text="@string/CheckFal" />
</RelativeLayout>
上述类中的pCal返回错误无法引用内部类中的非最终变量pCal

下面是DatePicker类:

package ir.smartlab.persindatepicker;

import info.androidhive.slidingmenu.R;
import ir.smartlab.persindatepicker.util.PersianCalendar;
import ir.smartlab.persindatepicker.util.PersianCalendarConstants;
import ir.smartlab.persindatepicker.util.PersianCalendarUtils;

import java.util.Date;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.NumberPicker;

public class PersianDatePicker extends LinearLayout {

    private NumberPicker yearNumberPicker;
    private NumberPicker monthNumberPicker;
    private NumberPicker dayNumberPicker;

    private int minYear;
    private int maxYear;
    private int yearRange;

    public PersianDatePicker(Context context) {
        this(context, null, -1);
    }

    public PersianDatePicker(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

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

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = inflater.inflate(R.layout.sl_persian_date_picker, this);
        yearNumberPicker = (NumberPicker) view.findViewById(R.id.yearNumberPicker);
        monthNumberPicker = (NumberPicker) view.findViewById(R.id.monthNumberPicker);
        dayNumberPicker = (NumberPicker) view.findViewById(R.id.dayNumberPicker);

        PersianCalendar pCalendar = new PersianCalendar();

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PersianDatePicker, 0, 0);

        yearRange = a.getInteger(R.styleable.PersianDatePicker_yearRange, 10);

        /*
         * Initializing yearNumberPicker min and max values If minYear and
         * maxYear attributes are not set, use (current year - 10) as min and
         * (current year + 10) as max.
         */
        minYear = a.getInt(R.styleable.PersianDatePicker_minYear, pCalendar.getPersianYear() - yearRange);
        maxYear = a.getInt(R.styleable.PersianDatePicker_maxYear, pCalendar.getPersianYear() + yearRange);
        yearNumberPicker.setMinValue(minYear);
        yearNumberPicker.setMaxValue(maxYear);

        int selectedYear = a.getInt(R.styleable.PersianDatePicker_selectedYear, pCalendar.getPersianYear());
        if (selectedYear > maxYear || selectedYear < minYear) {
            throw new IllegalArgumentException(String.format("Selected year (%d) must be between minYear(%d) and maxYear(%d)", selectedYear, minYear, maxYear));
        }
        yearNumberPicker.setValue(selectedYear);
        yearNumberPicker.setOnValueChangedListener(dateChangeListener);

        /*
         * initializng monthNumberPicker
         */
        boolean displayMonthNames = a.getBoolean(R.styleable.PersianDatePicker_displayMonthNames, false);
        monthNumberPicker.setMinValue(1);
        monthNumberPicker.setMaxValue(12);
        if (displayMonthNames) {
            monthNumberPicker.setDisplayedValues(PersianCalendarConstants.persianMonthNames);
        }
        int selectedMonth = a.getInteger(R.styleable.PersianDatePicker_selectedMonth, pCalendar.getPersianMonth());
        if (selectedMonth < 1 || selectedMonth > 12) {
            throw new IllegalArgumentException(String.format("Selected month (%d) must be between 1 and 12", selectedMonth));
        }
        monthNumberPicker.setValue(selectedMonth);
        monthNumberPicker.setOnValueChangedListener(dateChangeListener);

        /*
         * initializiing dayNumberPicker
         */
        dayNumberPicker.setMinValue(1);
        dayNumberPicker.setMaxValue(31);
        int selectedDay = a.getInteger(R.styleable.PersianDatePicker_selectedDay, pCalendar.getPersianDay());
        if (selectedDay > 31 || selectedDay < 1) {
            throw new IllegalArgumentException(String.format("Selected day (%d) must be between 1 and 31", selectedDay));
        }
        if (selectedMonth > 6 && selectedMonth < 12 && selectedDay == 31) {
            selectedDay = 30;
        } else {
            boolean isLeapYear = PersianCalendarUtils.isPersianLeapYear(selectedYear);
            if (isLeapYear && selectedDay == 31) {
                selectedDay = 30;
            } else if (selectedDay > 29) {
                selectedDay = 29;
            }
        }
        dayNumberPicker.setValue(selectedDay);
        dayNumberPicker.setOnValueChangedListener(dateChangeListener);

        a.recycle();
    }

    NumberPicker.OnValueChangeListener dateChangeListener = new NumberPicker.OnValueChangeListener() {

        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
            int year = yearNumberPicker.getValue();
            boolean isLeapYear = PersianCalendarUtils.isPersianLeapYear(year);

            int month = monthNumberPicker.getValue();
            int day = dayNumberPicker.getValue();

            if (month < 7) {
                dayNumberPicker.setMinValue(1);
                dayNumberPicker.setMaxValue(31);
            } else if (month > 6 && month < 12) {
                if (day == 31) {
                    dayNumberPicker.setValue(30);
                }
                dayNumberPicker.setMinValue(1);
                dayNumberPicker.setMaxValue(30);
            } else if (month == 12) {
                if (isLeapYear) {
                    if (day == 31) {
                        dayNumberPicker.setValue(30);
                    }
                    dayNumberPicker.setMinValue(1);
                    dayNumberPicker.setMaxValue(30);
                } else {
                    if (day > 29) {
                        dayNumberPicker.setValue(29);
                    }
                    dayNumberPicker.setMinValue(1);
                    dayNumberPicker.setMaxValue(29);
                }
            }
        }
    };

    public Date getDisplayDate() {
        PersianCalendar displayPersianDate = new PersianCalendar();
        displayPersianDate.setPersianDate(yearNumberPicker.getValue(), monthNumberPicker.getValue(), dayNumberPicker.getValue());
        return displayPersianDate.getTime();
    }

    public void setDisplayDate(Date displayDate) {
        setDisplayPersianDate(new PersianCalendar(displayDate.getTime()));
    }

    public PersianCalendar getDisplayPersianDate() {
        PersianCalendar displayPersianDate = new PersianCalendar();
        displayPersianDate.setPersianDate(yearNumberPicker.getValue(), monthNumberPicker.getValue(), dayNumberPicker.getValue());
        return displayPersianDate;
    }

    public void setDisplayPersianDate(PersianCalendar displayPersianDate) {
        int year = displayPersianDate.getPersianYear();
        int month = displayPersianDate.getPersianMonth();
        int day = displayPersianDate.getPersianDay();
        if (month > 6 && month < 12 && day == 31) {
            day = 30;
        } else {
            boolean isLeapYear = PersianCalendarUtils.isPersianLeapYear(year);
            if (isLeapYear && day == 31) {
                day = 30;
            } else if (day > 29) {
                day = 29;
            }
        }
        dayNumberPicker.setValue(day);

        minYear = year - yearRange;
        maxYear = year + yearRange;
        yearNumberPicker.setMinValue(minYear);
        yearNumberPicker.setMaxValue(maxYear);

        yearNumberPicker.setValue(year);
        monthNumberPicker.setValue(month);
        dayNumberPicker.setValue(day);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        // begin boilerplate code that allows parent classes to save state
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState);
        // end

        ss.datetime = this.getDisplayDate().getTime();
        return ss;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        // begin boilerplate code so parent classes can restore state
        if (!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }

        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        // end

        setDisplayDate(new Date(ss.datetime));
    }

    static class SavedState extends BaseSavedState {
        long datetime;

        SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            this.datetime = in.readLong();
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeLong(this.datetime);
        }

        // required field that makes Parcelables from a Parcel
        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

}

将pCal变量声明为final,并使用findViewById初始化PersandatePicker视图。 您可以像这样更改代码

 btnCheckFalAction = (Button) rootView.findViewById(R.id.btnCheckFal); 
     persianDatePicker = (PersianDatePicker) rootView.findViewById(R.id.persianDatePicker); 
     PersianCalendar pCal = persianDatePicker.getDisplayPersianDate();
<ir.smartlab.persindatepicker.PersianDatePicker
        android:id="@+id/persianDatePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        />
还可以像这样编辑xml

 btnCheckFalAction = (Button) rootView.findViewById(R.id.btnCheckFal); 
     persianDatePicker = (PersianDatePicker) rootView.findViewById(R.id.persianDatePicker); 
     PersianCalendar pCal = persianDatePicker.getDisplayPersianDate();
<ir.smartlab.persindatepicker.PersianDatePicker
        android:id="@+id/persianDatePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        />
很简单。 如果在执行过程中不必更改pCal的值,则将pCal设置为final。 或
如果在更大范围内没有任何问题,请将pCal设置为类变量。

谢谢,但在声明pCal之前添加final也无济于事。还是会撞车,可能是波斯的,泰皮克没有初始化。你能详细说明一下吗?!catlog上有很多错误。但我可以看到日期选择器,我可以更改值,但我单击提交按钮的部分是问题所在,我无法读取值