Day3 安裝資料庫吧 ! FireBase!


.先進這個網站 https://firebase.google.com/?hl=zh-tw

前往主控台
構建新專案> 選擇你要取的名字>按繼續>接下來回到主頁面>按一下進控制台>按安卓標籤



他會要你填寫你的套件名稱 請去Gradle>application Id>google-service.json下看你的applicationId加到app資料夾下
暱稱隨便填,然後sha-1不用寫 直接按繼續
接下來下載你的google-service.json檔,並將他加到app資料夾下

在 build.Grade(Project) 加入depencies
classpath 'com.google.gms:google-services:4.3.3'
另一個gradle(module.app):
apply plugin: 'com.google.gms.google-services' implementation 'com.google.firebase:firebase-core:17.0.0'

接下來按tools>firebase>realtime database>save and retrieve

connect ur app >add realtime (他幫你加了implementation) com.google.firebase:firebase-database:16.0.4'






切過去接下來創一個Realtime Database,因為是要測試用所以先以測試模式啟動就可以了

// 測試一下有沒有連成功,接下來在onCreate的地方下

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
myRef.setValue("Hello, World!");

接著看圖中的樣子就知道我們測試完成囉!

接著我們要來設計資料庫
在前文的設計圖中我們有了 標題 日期 時間 內容 跟優先度
但是為了區別不同的資料我們必須要再加個欄位就是ID 來分辨每筆的資料特殊性 在這裡我把ID取成KEY 你如果習慣用ID可以改成ID 還有一個是你在recycleview滑動的哪個位置 我們取名為position

我們先新增一個class用來當作資料庫回傳數據的地方
按app>右鍵>new>class 取名為todo
Key,date,desc,title,clock都是String,position,priority是int
之後按alt+insert>getter and setter 可以快速創建get和set的function
創建那兩個主要是用來取數據 跟 拿數據做為用途
對了也要先創constructor這後面不會用到但為了要先塞假資料所以要先做
一樣alt+insert>constructor 除了position的地方都按

接下來跳回firebase 先把hello world刪掉
回mainActivity
在oncreate的地方新增 > 這是為了測試能不能符合資料
然後先random一個隨機的id 這也是為了測試能不能寫入
private DatabaseReference mDatabase;

在onCreate()內加入

mDatabase = FirebaseDatabase.getInstance().getReference()
        .child("Todo");
Integer doesNum = new Random().nextInt(); //id
String keydoes = Integer.toString(doesNum);
Todo user = new Todo("111", "111","111","111","111",0);
Todo user1 = new Todo("222", "222","222","222","222",0);
mDatabase.child("Todo"+keydoes).setValue(user);
mDatabase.child("Todo"+keydoes).setValue(user1)

接下來重開你的app 檢查firebase的地方有沒有成功創建和裡面有沒有資料
有的話就可以進行下一步了

接下來我們要來試著顯示剛剛寫入資料庫的資料,先切回去activity.xml
在data 標籤內加入兩個variable標籤,這裡的variable是可以讓你在當前的xml下使用的,也可以關連到其他class,像是這裡的view就關聯到HomeContractView

<data>
    <variable
        name="data"
        type="String" />
    <variable
        name="view"
        type="com.example.alarmmanagerproject.home.HomeContract.View" />
</data>

然後新建一個interface,並命名為HomeContract,這是為了讓activity跟xml聯絡,主要是在架構化下找資料會更好找

public interface HomeContract {
    interface View  {
        void onAddClick();
        void onSearchClick();
        void onDelClick(String key);
    }
}

接著我們在之下加入三個function,分別是增加 搜尋 跟刪除 刪除的話因為要滑動刪除所以需要傳入資料的key當參數
加完之後分別在Add的button下加
android:onClick="@{() -> view.onAddClick()}"
Search的Button下加
android:onClick="@{() -> view. onSearchClick ()}"
他是一個無參數的function 第一個()代表無參數 ->代表你的主體
EX: (參數)-> {主體},但是因為我們主體只有一個且一行所以不用{ }
這代表當你按的時候會連結到HomeConstarct下的onAddClick跟onSearch方法,但是HomeConstract是interface只是一個虛擬的介面,需要實作才能真正實現方法,這也是我們用來結合activity跟view的方式

接下來我們切到HomeActivity首先我們必須先implement(實作)上面HomeConstract的方法
像是這樣
public class HomeActivity extends AppCompatActivity implements HomeContract.View

接下來 還記得我們使用了Databinding嗎?所以我們要先初始化databinding的部分,先寫一個Function命名為init

public  void  init(){
    view=this;
    activityHomeBinding = DataBindingUtil.setContentView(this, R.layout.activity_home);
    activityHomeBinding.setView(this);
    //activityHomeBinding.recyclerview.setAdapter();
}

並在onCreate()的地方呼叫他
然後Set view的部分是因為我們要用databinding裡面的variable 這裡必須填this讓他讀到這個view是這裡

之後我們要正式拿取資料 用Firebase提供的ValueEventlistener 他是會監聽你的資料
ValueEventListener postListener = new ValueEventListener(){…}
先創一個arraylist預存資料,因為從資料庫回傳回來的資料是Todo的形式所以new的Arraylist也必須如此,這個list是為了傳入adapter做的
private ArrayList<Todo> todos=new ArrayList<>();
一開始要先清除所有data 不然有可能會重複寫入 所以下todos.clear()清除所有資料,然後創一個Todo類別的資料將回傳的資料丟入
Todo p = dataSnapshot1.getValue(Todo.class);
接下來再將p的資料寫入之前的list裡面
todos.add(p);
接下來呼叫recycleview 因為databinding的關係不用findviewByid他已經知道是哪個了,只要你的binding.物件id就可以了
然後還記得我們的recycleview嗎,可以視作為很多資料的小集合,我們要把資料寫入,但是寫入之前我們要先創資料的item.xml跟adapter
Adapter主要的作用是將item綁上去recycleview
但是我們還是先在裡面寫

homeAdapter=new HomeAdapter(todos,view);
        activityHomeBinding.recyclerview.setLayoutManager(new LinearLayoutManager(HomeActivity.this));
        activityHomeBinding.recyclerview.setAdapter(homeAdapter);

LayoutManager的作用就是負責元素的布局和使用。
我們先設定他是LinearLayoutManager,就是前面說過的線性布局
然後接下來setAdapter就是將recycleview綁定到這個Adapter

ValueEventListener postListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        // Get Post object and use the values to update the UI
        todos.clear();
    for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
        Log.d("111", "onDataChange: " + dataSnapshot1);
        Todo p = dataSnapshot1.getValue(Todo.class);
        Log.d("test", "onDataChange: "+p.getPriority());
        todos.add(p);
    }
        homeAdapter=new HomeAdapter(todos,view);

        activityHomeBinding.recyclerview.setLayoutManager(new LinearLayoutManager(HomeActivity.this));
        activityHomeBinding.recyclerview.setAdapter(homeAdapter);
    }

接下來我們需要有個Adapter,在app右鍵 new一個新的class取名為HomeAdapter,或是直接在HomeAdpter紅色的地方按alt+enter選擇create new class,並先宣告一些值,讓他extends Recycleview Adapter然後裡面要放viewholder viewholder裡面放你你所使用的databinding這樣他才知道你是用哪個view接著紅色的地方按alt+enter引入需要的方法或class,可以看到他有幾個方法,

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder<HomeItemBinding>> {
private Todo todoItem;
private HomeItemBinding homeItemBinding;
private ArrayList<Todo> todoList;
private String key;
private Context c;
private HomeContract.View view;

public HomeAdapter(ArrayList<Todo> todoList,HomeContract.View view) {
    this.todoList = todoList;
    this.view=view;
} …
}

onCreateViewHolder(ViewGroup parent, int viewType) 是負責幫你承載創建佈局的,這裡的第二個參數就是View的類型,可以根據這個類型判斷去創建不同item的ViewHolder。
我們在裡面增加LayoutInflater是用來載入頁面的,無論是動態載入或非動態載入都需要,然後他是從這個上層的context(Recycleview)拿的
接著再由binding引入進去

LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
c = parent.getContext();
homeItemBinding = homeItemBinding.inflate(layoutInflater, parent, false);
return new ViewHolder<>(homeItemBinding);

onBindViewHolder()方法中通過holder的getBinding()方法得到item對應的Binding 物件,填充數據
我們在裡面寫一個判斷你拿到的priority分別是多少,來改變他的顏色,並綁定

if (todoList.get(position).getPriority()==1)
        {
            holder.itemView.setBackgroundColor(Color.RED);
        }
        if (todoList.get(position).getPriority()==2){
            holder.itemView.setBackgroundColor(Color.YELLOW);
        }
        if (todoList.get(position).getPriority()==3){
            holder.itemView.setBackgroundColor(Color.BLUE);
        }
        holder.bind(todoItem);

getItemCount回傳你的list有多長,並獲取數據,如果是null就回傳他的值是0不是的話就回傳他的list.size
return todoList == null ? 0 : todoList.size();

接下來創建ViewHolder 一樣要extends ViewHolder跟ViewDataBinding,
然後setvariable的BR類是databinding自動幫你建造的數據然後你在前面傳入bind的數據後,記得要加上executePendingBindings,這非常重要 他才會幫你自動更新


public class ViewHolder<B extends ViewDataBinding> extends RecyclerView.ViewHolder {

    private final B mViewDataBinding;

    public ViewHolder(B binding) {
        super(binding.getRoot());
        mViewDataBinding = binding;
    }

    public void bind(final Object object) {
        mViewDataBinding.setVariable(com.example.alarmmanagerproject.BR.data, object);
        mViewDataBinding.executePendingBindings();
    }

}

接著讓程式run起來 > 按綠色的三角形
在去看firebase就會有資料跟顯示資料囉!
今天就差不多這樣啦

完整的activity

public class HomeActivity extends AppCompatActivity implements  HomeContract.View {
    DatabaseReference databaseReference;
    ActivityHomeBinding activityHomeBinding;
    HomeAdapter homeAdapter;
    ArrayList<Todo> todos=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();
        DatabaseReference mDatabase;// ...
        mDatabase = FirebaseDatabase.getInstance().getReference();
        Integer doesNum = new Random().nextInt(); //id
        String keydoes = Integer.toString(doesNum);
        Todo user = new Todo("111", "111","111","111","111",0);
        Todo user1 = new Todo("222", "222","222","222","222",0);
        mDatabase.child("DoesApp"+keydoes).setValue(user);
        mDatabase.child("DoesApp"+keydoes).setValue(user1);
        ValueEventListener postListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                // Get Post object and use the values to update the UI
            for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
                Log.d("111", "onDataChange: " + dataSnapshot1);
                Todo p = dataSnapshot1.getValue(Todo.class);
                Log.d("111", "onDataChange: " + p.getTitle());
                todos.add(p);
            }
                Log.d("test", "onDataChange: "+todos.get(0).getTitle());
                homeAdapter=new HomeAdapter(todos);
                activityHomeBinding.recyclerview.setLayoutManager(new LinearLayoutManager(HomeActivity.this));
                activityHomeBinding.recyclerview.setAdapter(homeAdapter);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                // Getting Post failed, log a message

                // ...
            }
        };
        mDatabase.addValueEventListener(postListener);

       // setContentView(R.layout.activity_home);
    }
#Android
初學者也能學會的超詳細介紹






Related Posts

[ 學習筆記系列 ] 後端基礎 (全) - MySQL 語法、基礎 PHP 與 Session / Cookie

[ 學習筆記系列 ] 後端基礎 (全) - MySQL 語法、基礎 PHP 與 Session / Cookie

第一次創建 Gin 網站就卡住

第一次創建 Gin 網站就卡住

Android Status bar 深色模式設定

Android Status bar 深色模式設定



Sponsored



Comments