Day04 增加資料(上) + RecycleView Adapter


第四天

今日目標:增加資料(上)

我們先從回到HomeActiviy然後嘗試按按鈕就跳躍到AddActivity
還記得我們的onAddClick嗎 這時候我們要在裡面寫一些東西
要從一個Activity傳東西到另一個,或是單純的跳轉都可以用Intent(可以將它看作事件),題外話如果你有要傳資料可以用bundle傳
先new一個Intent 第一個參數是你的目前位置 第一個是你要跳轉的位置
還記得生命週期嗎 這時候我們要開啟新的Activity要用startActiviy
不記得的話可以回第二天看喔

@Override
public void onAddClick() {
    Intent intent=new Intent(HomeActivity.this, AddActivity.class);
    startActivity(intent);
}

接著我們先重啟app 按綠色的三角形 按一下增加的按鈕測試看看有沒有跳過去,有的話開啟activiy_add.xml
這次一樣在data的部分加上

<data>
    <variable
        name="view"
        type="com.example.alarmmanagerproject.add.AddConstract.View" />
</data>

然後一樣用一個Interface接中間的東西,並我們new一個新的interface取名為
AddConstract,裡面有四個方法分別是按時間 按確認 選擇優先順序

public interface AddConstract {
    interface View  {
        void onTimeClick();
        void onDateClick();
        void onSubmit();
        void onPrioritySelected();
    }
}

在日期的TextView加上
android:onClick="@{()->view.onDateClick()}"
在時間的TextView加上
android:onClick="@{()->view.onTimeClick()}"
在送出的Button加上
android:onClick="@{()->view. onSubmit ()}"
在三個radioButton加上
android:onClick="@{()->view. onPrioritySelected()}"

接著我們回AddActivity先實作AddConstract

public class AddActivity extends AppCompatActivity
 implements AddConstract.View{…}

跟將一些要用到的變數宣告

private DatabaseReference databaseReference;
private Integer mPriority;
private Calendar store;
private boolean status=false;
int year_x,month_x,day,hour_x,minute_x,second_x;
private String key;
ActivityAddBinding activityAddBinding;

先init我們的databinding,並記得在onCreate加上他
public void init() {
    activityAddBinding = DataBindingUtil.setContentView(this, R.layout.activity_add);
    activityAddBinding.setView(this);
}

接著我們也要設定優先度的部分將他存入資料庫,設定你按了button1會設定成1,2設定成2… 判斷有沒有按的方式是用 .isChecked(),這在checkButton跟radio中都可以用

public void onPrioritySelected() {
    if ((activityAddBinding.radButton1).isChecked()) {
        mPriority = 1;
    } else if ((activityAddBinding.radButton2).isChecked()) {
        mPriority = 2;
    } else if ((activityAddBinding.radButton3).isChecked()) {
        mPriority = 3;
    }
}

接著來處理時間的部分,首先我們必須實作兩個onClickListener
public class AddActivity extends AppCompatActivity implements AddConstract.View, TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener{…}

並且在onTimeClicick中使用新建的Fragment,好我們又接觸到一個新的東西,Fragment,Fragment是甚麼呢?
Fragment 代表一種行為或 Activity 中的一部分使用者介面。您可以合併單一 Activity 中的多個片段,建立多窗的UI(EX 一台平板上同一個app內有兩個分割畫面,像是子母畫面那樣),而且Fragment可以在很多不同的activity上分別使用,也可以模組化。但是他必須一定都要嵌入activity(activity才是真正畫面交互的東西),生命週期也會隨著Activity使用,Activity暫停或摧毀都會影響到Fragment,但是Fragment的暫停或摧毀不一定影響到Activity,個人認為有點類似父子的概念。

@Override
public void onTimeClick() {
    DialogFragment timePicker = new TimePickerFragment();
    timePicker.show(getSupportFragmentManager(), "time picker");
}

@Override
public void onDateClick() {
   DatePickerFragment datePickerDialog=new DatePickerFragment();
   datePickerDialog.show(getSupportFragmentManager(),"date");
}

接著我們從紅紅的地方按alt+enter來new兩個新的frament
第一個是TimerFragment 他們一律都要extends DialogFragment
內部使用的是Calendar為java內建的函式庫,專門處理日期,回傳的是小時秒數的部分
/注意他format(可以看做格式化)的方式是採用24HR的 小心不要選錯/

public class TimePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(), hour, minute, DateFormat.is24HourFormat(getActivity()));
    }
}

第二個是DateFragment由於方式都大同小異因此不贅述了,主要是format的方式不同
public class DatePickerFragment extends DialogFragment  {

    private static final String TAG = "DatePickerFragment";

    private SimpleDateFormat dateFormatterEntry = new SimpleDateFormat("M/dd/yyyy");
    private Calendar calendar;
    int year;
    int month;
    int day;
    @Override
    @NonNull
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Log.i(TAG, "onCreateDialog");

        calendar = Calendar.getInstance();
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DAY_OF_MONTH);


        return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener) getActivity(), year, month, day);
    }
}

接著再來實作 TimeSet() DateSet的部分,很明顯這個是來設定時間的
他傳入的hourOfDay, minute,就是你選下去的時間喔
然後傳入設定text前還要在formate現在時間一遍
setText()可以用來設定你這個textViw or EditView的text要甚麼
然後Calendar.getInstance();這個是拿到你現在的實例 也就是初始化的意思

@Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) 
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, hourOfDay);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, 0);
        hour_x=hourOfDay;
        minute_x=minute;
        second_x=0;
        String timeText = DateFormat.getTimeInstance(DateFormat.SHORT).format(c.getTime());
activityAddBinding.timePicker.setText(timeText);

    }

  @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        Calendar f = Calendar.getInstance();
        year_x=year;
        month_x=month;
        day=dayOfMonth;
        f.set(Calendar.YEAR, year);
        f.set(Calendar.MONTH, month);
        f.set(Calendar.DAY_OF_MONTH, dayOfMonth);
//        store = Calendar.getInstance();
//        store = f;
        String ff=DateFormat.getDateInstance(DateFormat.FULL).format(f.getTime());
        activityAddBinding.datePicker.setText(ff);
    }

在來實作我們拿到的資料,用dataSnapshot.getRef().child(“你要的資料名”).setValue來設定資料,而拿EditText你輸入的資料則是用getText()去拿
/小雷點 getText()拿到後記得要toString()轉成String的型態/
然後拿到資料後再用一個Intent傳回我們的HomeActivity

private  void  setDatabaseReference(){
    Integer todoNum = new Random().nextInt();
    key = Integer.toString(todoNum);
    databaseReference = FirebaseDatabase.getInstance().getReference()
            .child("Todo").child("Todo" + todoNum);
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            dataSnapshot.getRef().child("priority").setValue(mPriority);
            dataSnapshot.getRef().child("clock").setValue(activityAddBinding.timePicker.getText().toString());
            dataSnapshot.getRef().child("key").setValue(key);
            dataSnapshot.getRef().child("title").setValue(activityAddBinding.title.getText().toString());
            dataSnapshot.getRef().child("desc").setValue(activityAddBinding.discription.getText().toString());
            dataSnapshot.getRef().child("date").setValue(activityAddBinding.datePicker.getText().toString());
            Intent intent = new Intent(AddActivity.this, HomeActivity.class);
            startActivity(intent);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

最後在onSubmit的地方 記得寫入setDatabaseReference方法

    @Override
    public void onSubmit() {
        setDatabaseReference();
    }

大概就先這樣囉 明天會講四大元件之一的BroadCast ,主要是用來做我們背景定時提醒的部分,明天見!

#Android





初學者也能學會的超詳細介紹

留言討論