RecyclerView 튜토리얼이 포함된 Android Firebase 실시간 데이터베이스
이 부분에서 우리는 몇 가지 RecyclerView 및 Firebase 실시간 데이터베이스 예제를 살펴보고자 합니다. 기본적으로 recyclerview에서 추가, 검색 및 표시와 같은 여러 CRUD 작업을 수행하는 방법입니다.
Firebase 실시간 데이터베이스란 무엇입니까?
Firebase 실시간 데이터베이스는 Google이 소유한 Firebase 플랫폼에서 제공하는 서비스 중 하나입니다.
기본적으로 우리는 Database BAAS 또는 Database Backend As A Service라고 부릅니다. 클라우드에서 호스팅됩니다.
Firebase 실시간 데이터베이스가 필요한 이유
그것은 여러 면에서 이미 알고 있는 많은 데이터베이스와 다릅니다. 이러한 방식이 Firebase 실시간 데이터베이스에 이점을 제공합니다.
- SQLite 및 Realm과 같은 다른 것들은 로컬에서 호스팅되는 반면 클라우드에서 호스팅됩니다. 이를 통해 Firebase 실시간 데이터베이스를 많은 앱에서 액세스할 수 있습니다. SQLite 및 Realm과 같은 데이터베이스는 단일 앱 내에서 현지화됩니다. Firebase 실시간 데이터베이스는 많은 애플리케이션에서 액세스할 수 있습니다.
- 실시간입니다. 이것이 가장 큰 차이점입니다. 즉, 데이터를 저장하면 연결된 모든 앱의 데이터가 자동으로 즉시 업데이트됩니다. 따라서 채팅 및 메시징 앱과 같은 많은 유형의 앱, 즉석 동기화가 필요한 앱에 적용할 수 있습니다.
- sqlite의 테이블과 달리 json 형식으로 데이터를 저장합니다. 이를 통해 Firebase 실시간 데이터베이스를 확장할 수 있습니다.
- 무료 및 유료 플랜이 있습니다. 이것은 학습 및 상업적 목적으로 사용할 수 있는 최고의 시나리오입니다.
RecyclerView 란 무엇입니까
RecyclerView는 대용량 데이터 세트를 효율적으로 렌더링할 수 있는 Android 어댑터 뷰입니다. 일반적으로 Android에서 목록 데이터를 렌더링하려면 어댑터 보기와 어댑터가 필요합니다. adapterview는 목록 위젯이며 예에는 ListView, Gridview, Spinner 및 RecyclerView가 포함됩니다.
그런 다음 어댑터는 일반적으로 어댑터 보기를 데이터 소스에 연결하는 역할을 합니다. 사실 일반적으로 사용자 정의 레이아웃을 사용하여 단일 목록 항목을 표시할 수 있습니다. 이 레이아웃은 어댑터 내부에서도 확장됩니다.
여기에서 RecyclerView에 대해 자세히 알아보세요.
왜 RecyclerView인가?
우리는 여러 어댑터 보기가 안드로이드에서 데이터 표현에 사용될 수 있다고 말했습니다. ListView, GridView, Spinner 등이 있습니다. ListView는 RecyclerView가 도입되기 전까지 가장 많이 사용되었습니다.
요즘 리사이클러뷰는 유연성과 성능 때문에 가장 일반적으로 사용되는 어댑터뷰입니다. RecyclerView는 목록 보기에서 그리드/지그재그 보기, 테이블 보기, 캘린더 등 거의 모든 유형의 보기를 작성하는 데 사용할 수 있습니다.
이 사실은 많은 시나리오에서 매우 특별하고 유용합니다. 그러나 다른 어댑터 보기보다 훨씬 어렵지 않습니다.
사용된 도구
이 예제는 다음 도구로 작성되었습니다.
- Microsoft Windows 8.1 - 이것은 내 운영 체제입니다.
- Android Studio - Jetbrains와 Google의 IDE(통합 개발 키트)입니다.
- Genymotion 에뮬레이터 - 애플리케이션을 테스트하는 데 사용합니다.
- 언어 : 자바 - 자바는 가장 대중적인 프로그래밍 언어입니다.
1. Android Firebase => Simple RecyclerView - 저장, 검색 후 표시
[center]Android Firebase 실시간 데이터베이스 recyclerView Tutorial[/center]
이것은 안드로이드 Firebase RecyclerView 튜토리얼입니다. Firebase에 데이터를 저장하는 방법은 간단한 Recyclerview에서 해당 데이터를 검색한 다음 표시합니다. 우리는 데이터의 단일 필드만 사용합니다.
이 예에서 배우는 일반 개념.
다음은 이 튜토리얼에서 배울 수 있는 몇 가지 개념입니다.
- Firebase란 무엇이며 RecyclerView란 무엇이며 왜 사용하는가?
- edittext에서 google Firebase 실시간 데이터베이스로 데이터를 저장하는 방법.
- 'DatabaseReference' 인스턴스에 이벤트를 연결한 다음 자바 배열 목록을 채워 Firebase 데이터베이스에서 데이터를 가져오거나 검색하거나 읽는 방법
- 검색된 데이터를 'RecyclerView.Adapter' 서브클래스의 인스턴스에 바인딩하는 방법.
- Firebase에서 데이터베이스를 생성하고 운영하는 방법.
- Recyclerview가 있는 Firebase 예시 앱.
- Firebase 데이터베이스 동기화
배우게 될 특정 개념
- Firebase 데이터베이스 참조를 사용하는 방법.
- Firebase 데이터베이스 참조에 자식을 추가하는 방법
데모
이 튜토리얼의 프로젝트 데모는 다음과 같습니다.
설정 및 구성
(ㅏ). 기본 활동 프로젝트 만들기
- 먼저 안드로이드 스튜디오에서 새 프로젝트를 생성합니다.
(b). Firebase 생성 및 구성 파일 다운로드
Firebase 콘솔로 이동하여 Firebase 앱을 만들고 앱 ID를 등록하고 google-services.json
파일을 다운로드합니다. 앱 폴더에 추가합니다.
(씨). Maven 저장소 URL 지정
프로젝트 수준(프로젝트 폴더) build.gradle
로 이동하고
- 아래와 같이 Google 서비스 클래스 경로를 추가합니다.
- maven 저장소 URL 추가
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
이렇게 하면 maven.google com
에서 Firebase를 가져올 수 있습니다. Firebase는 타사 라이브러리이며 프로젝트에서 사용하려면 다운로드해야 합니다.
(d). Firebase 종속성 추가
앱 수준(앱 폴더) build.gradle에 추가하면 여러 종속성을 추가해야 합니다. appcompat
, design
및 cardview
와 같은 지원 라이브러리를 추가했습니다. AppCompat은 MainActivity
가 파생될 클래스인 AppCompatActivity를 제공합니다. 'implementation' 문을 사용하여 추가합니다.
design
지원은 우리의 목록 위젯인 recyclerveiew를 제공할 것입니다. 이것이 Firebase에서 쿼리하는 데이터로 채울 것입니다. 반면에 'cardview'를 사용하면 cardview를 항목 보기로 사용할 수 있습니다. 리사이클러뷰는 카드뷰로 구성됩니다.
그런 다음 Firebase Core와 Firebase Database를 추가했습니다. Firebase 기억은 플랫폼이고 Firebase 데이터베이스는 우리가 데이터를 저장하는 데이터베이스입니다. 이후 버전을 사용할 수 있습니다. 그러나 우리가 한 것처럼 Google 서비스를 적용하는 것을 잊지 마십시오.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:23.3.0'
implementation 'com.android.support:design:23.3.0'
implementation 'com.android.support:cardview-v7:23.3.0'
implementation 'com.google.firebase:firebase-core:11.8.0'
implementation 'com.google.firebase:firebase-database:11.8.0'
}
apply plugin: 'com.google.gms.google-services'
위와 같이 '플러그인 적용: 'com.google.gms.google-services''를 확인하세요.
2. 우리의 자바 코드
Java 프로그래밍 언어를 사용하여 이 예제를 작성합니다. 따라서 앱의 다양한 부분을 여러 클래스로 분리합니다.
(ㅏ). 우리의 모델 클래스
- 우리의 데이터 객체 클래스인가
- 빈 생성자가 있어야 합니다.
- 다른 생성자에 데이터를 생성, 전달 및 사용할 수 있습니다.
모델 또는 데이터 객체 클래스는 기본적으로 데이터를 모델링할 클래스를 나타냅니다. 어떤 형태의 데이터로 작업할 때 항상 구체적인 단순 클래스에서 데이터를 나타내는 것이 좋습니다. 그런 다음 필요에 따라 해당 클래스의 개체를 쿼리할 수 있습니다. 일반적으로 이러한 유형의 클래스에는 접근자 메서드라고 하는 것이 있습니다. 이러한 메서드는 항상 공개되므로 항상 비공개인 클래스의 속성을 노출하는 방법을 제공합니다.
우리의 경우 'Spacecraft'라는 클래스를 만들었습니다. 해당 클래스에는 해당 우주선의 이름을 담기 위한 이름만 있는 단일 속성이 있습니다. 그런 다음 클래스에 공개 기본 생성자를 제공합니다. 이것은 일반적으로 데이터베이스 스키마를 자동으로 생성하기 위해 데이터 개체를 읽는 데 의존하는 데이터베이스 엔진에 필요한 기능입니다. Firebase 데이터베이스는 Java 및 Android용 로컬 데이터베이스인 Realm과 같은 역할을 합니다.
그런 다음 클래스에 getName
및 setName
접근자 메서드를 제공합니다.
package com.tutorials.hp.firebasesimplerecyclerview.m_Model;
public class Spacecraft {
String name;
//EMPTY CONSTR
public Spacecraft() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(b). FirebaseHelper 클래스
- 기본적으로 CRUD 클래스입니다.
- 여기에서 Firebase 데이터베이스에 대한 읽기 및 쓰기를 수행합니다.
- 데이터를 유지하기 위해 setValue()를 사용합니다.
- setValue() 메서드를 호출하기 전에 push()를 호출하여 교체가 아닌 데이터베이스에 데이터를 추가하도록 합니다.
- 우리는 간단한 arraylist를 채웁니다.
Firebase에서 데이터를 저장하고 쿼리하거나 읽을 수 있도록 이 클래스인 'FirebaseHelper' 클래스를 만들었습니다. 클래스를 호스팅할 패키지를 정의하는 것으로 시작합니다. 그런 다음 com.google.firebase.database
의 여러 클래스를 포함하여 가져오기를 추가합니다.
다음을 포함하여 여러 인스턴스 필드를 정의했습니다.
- DatabaseReference -- 데이터베이스 참조입니다.
- 부울 값 - 성공적으로 저장했는지 여부를 결정합니다.
- ArrayList - Firebase에서 가져온 데이터를 보관합니다.
생성자를 통해 데이터베이스 참조를 수신하는 것으로 시작합니다. 그런 다음 유지 관리한 로컬 인스턴스 필드에 데이터베이스 참조를 할당합니다.
FirebaseDatabase에 데이터 저장
그런 다음 Firebase 데이터베이스에 데이터를 저장하는 메서드를 정의합니다. 이 메서드는 Spacecraft 개체를 매개변수로 받습니다. 외부 세계에서 'Spacecraft' 개체를 수신하고 있다는 점을 감안할 때 먼저 null이 있는지 확인하는 것이 이상적입니다.
Firebase에 데이터를 저장하려면
db.child("Spacecraft").push().setValue(spacecraft);
이 경우 db
는 DatabaseReference
입니다. child()
메서드를 통해 자식 노드를 얻습니다. 그런 다음 "테이블"의 이름을 전달합니다. 그런 다음 push()
메서드를 사용하여 Firebase에 데이터를 푸시합니다. 그러나 우리는 우리가 푸시하는 값을 설정해야 합니다. 우리는 spacecraft
객체를 설정하기 위해 setValue
메소드를 사용합니다. 이것이 Firebase 데이터베이스에 데이터를 저장하는 방법입니다. 우리는 DatabaseException
을 잡기 위해 try catch 블록을 사용했습니다.
Firebase 데이터베이스에서 데이터 검색
Firebase 실시간 데이터베이스에서 데이터를 수신하고 ArrayList를 채웁니다. 그런 다음 나중에 해당 ArrayList가 recyclerview 어댑터의 데이터 소스로 사용됩니다.
Firebase에서 데이터를 읽으려면 'ChildEventListener'를 데이터베이스 참조에 연결해야 합니다. 그런 다음 데이터 노드의 변경 사항을 수신합니다. 예를 들어 자식 노드가 추가, 수정, 제거 또는 취소되면 데이터 스냅샷이 포함된 콜백 메서드를 얻습니다. 그런 다음 해당 데이터 스냅샷에서 데이터를 읽을 수 있습니다.
그런 다음 각 반복에서 데이터 스냅샷 자식의 'getValue' 메서드를 호출하여 개체를 얻을 수 있습니다. DataSnapshot 개체에서 데이터를 읽는 것은 쉽습니다. 당신은 단순히 자식을 통해 루프:
for (DataSnapshot ds : dataSnapshot.getChildren())
{
String name=ds.getValue(Spacecraft.class).getName();
spacecrafts.add(name);
}
전체 코드는 다음과 같습니다.
package com.tutorials.hp.firebasesimplerecyclerview.m_FireBase;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.tutorials.hp.firebasesimplerecyclerview.m_Model.Spacecraft;
import java.util.ArrayList;
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
ArrayList<String> spacecrafts=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//SAVE
public Boolean save(Spacecraft spacecraft)
{
if(spacecraft==null)
{
saved=false;
}else {
try
{
db.child("Spacecraft").push().setValue(spacecraft);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//READ
public ArrayList<String> retrieve()
{
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return spacecrafts;
}
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
String name=ds.getValue(Spacecraft.class).getName();
spacecrafts.add(name);
}
}
}
(씨). MyViewHolder 클래스
- 네, 뷰홀더 클래스입니다.
- 재활용을 위해 준비된 사용을 위한 보기 보유
package com.tutorials.hp.firebasesimplerecyclerview.m_UI;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.tutorials.hp.firebasesimplerecyclerview.R;
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView nameTxt;
public MyViewHolder(View itemView) {
super(itemView);
nameTxt=(TextView) itemView.findViewById(R.id.nameTxt);
}
}
'MyViewHolder'는 ViewHolder 클래스입니다. 이는 recyclerview에서 뷰를 재활용하기 위해 항상 필요했습니다. 그러나 클래스를 recyclerview 뷰홀더로 바꾸려면 위에서 본 것처럼 Recyclerview.ViewHolder
클래스에서 파생되어야 합니다. 우리는 RecyclerView
자체를 포함하여 여러 클래스를 가져오는 것으로 시작했습니다.
우리 클래스에서는 nameTxt
라는 TextView를 유지 관리했습니다. 그런 다음 MyViewHolder
생성자가 View 객체를 가져왔습니다. 그 View 객체는 Recyclerview.ViewHolder
인 슈퍼 클래스로 전달되었습니다.
그런 다음 레이아웃 사양에서 nameTxt
를 참조했습니다.
9. MyAdapter 클래스
- 레이아웃 인플레이션을 담당합니다.
- 뷰에 대한 데이터 바인딩에도 사용됩니다.
package com.tutorials.hp.firebasesimplerecyclerview.m_UI;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tutorials.hp.firebasesimplerecyclerview.R;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<String> spacecrafts;
public MyAdapter(Context c, ArrayList<String> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.nameTxt.setText(spacecrafts.get(position));
}
@Override
public int getItemCount() {
return spacecrafts.size();
}
}
어댑터는 Android가 데이터 수집과 함께 작동하는 방식에서 중요합니다. 모바일 장치는 HTC, Samsung, F7, Apple iOS, Infinix 등이며 모두 데이터 목록을 렌더링해야 하는 많은 앱입니다. 그것은 바로 모바일 장치의 특성입니다. 화면은 항상 작기 때문에 스크롤할 수 있는 항목을 표시하는 것이 적절합니다.
그리고 RecyclerView는 대용량 데이터 세트를 표시하기 위한 최고의 어댑터 뷰입니다. 이러한 데이터 세트는 Firebase와 같은 클라우드에서 가져올 수 있습니다. 그리고 실제로 이 경우 데이터는 Firebase 실시간 데이터베이스에서 가져옵니다. 그래서 우리는 이미 수집한 데이터로 지금까지 ArrayList를 채웠습니다. 이제 해당 데이터를 바인딩할 시간입니다. 그러나 어댑터가 필요합니다.
어댑터:
- 데이터를 어댑터 보기에 바인딩할 수 있습니다.
- 사용자 지정 어댑터 보기를 설계할 수 있도록 사용자 지정 레이아웃을 보기로 확장하는 데 도움을 주세요.
RecyclerView.Adapter<MyViewHolder>
에서 파생하여 recyclerview 어댑터를 만듭니다. 일반 매개변수는 ViewHolder입니다. 해당 클래스에서 파생하면 세 가지 메서드를 재정의해야 합니다.
getItemCount
- 리사이클러 뷰에서 렌더링할 항목 수를 반환합니다.onCreateViewHolder
- 인플레이션이 발생하는 곳입니다. 인플레이션을 위해 LayoutInflater를 사용합니다.onBindViewHolder
- ViewHolder 클래스에서 정의한 위젯에 데이터를 바인딩하는 곳입니다.
한편 생성자는 Context 객체와 데이터의 arraylist를 가져왔습니다.
(d). 우리의 주요 활동
- 실행기 활동.
- RecyclerView를 참조하고 해당 layoutManager와 어댑터를 설정합니다.
- FAB 버튼 클릭 시 입력 대화 상자를 표시합니다.
- DatabaseReference를 초기화하여 Firebase를 설정합니다.
package com.tutorials.hp.firebasesimplerecyclerview;
import android.app.Dialog;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebasesimplerecyclerview.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebasesimplerecyclerview.m_Model.Spacecraft;
import com.tutorials.hp.firebasesimplerecyclerview.m_UI.MyAdapter;
public class MainActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper helper;
RecyclerView rv;
EditText nameEditTxt;
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//SETUP RV
rv= (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
//SETUP FB
db=FirebaseDatabase.getInstance().getReference();
helper=new FirebaseHelper(db);
//ADAPTER
adapter=new MyAdapter(this,helper.retrieve());
rv.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
displayInputDialog();
}
});
}
private void displayInputDialog()
{
Dialog d=new Dialog(this);
d.setTitle("Save To Firebase");
d.setContentView(R.layout.input_dialog);
nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
Button saveBtn= (Button) d.findViewById(R.id.saveBtn);
//SAVE
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//GET DATA
String name=nameEditTxt.getText().toString();
//SET DATA
Spacecraft s=new Spacecraft();
s.setName(name);
//VALIDATE
if(name.length()>0 && name != null)
{
if(helper.save(s))
{
nameEditTxt.setText("");
adapter=new MyAdapter(MainActivity.this,helper.retrieve());
rv.setAdapter(adapter);
}
}else
{
Toast.makeText(MainActivity.this, "Name Cannot Be Empty", Toast.LENGTH_SHORT).show();
}
}
});
d.show();
}
}
11. 우리의 레이아웃
(ㅏ). 활동_main.xml
이것은 우리의 주요 활동 레이아웃입니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context="com.tutorials.hp.firebasesimplerecyclerview.MainActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
(b). 내용_main.xml
여기에서 이 경우에는 adapterview를 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.firebasesimplerecyclerview.MainActivity"
tools_showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android_id="@+id/rv"
android_layout_width="match_parent"
android_layout_height="wrap_content"
/>
</RelativeLayout>
(씨). 입력_dialog.xml
- 입력 대화 상자 레이아웃을 정의합니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="15dp"
android_paddingRight="15dp"
android_paddingTop="10dp">
<android.support.design.widget.TextInputLayout
android_id="@+id/nameLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/nameEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Name" />
</android.support.design.widget.TextInputLayout>
<Button android_id="@+id/saveBtn"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Save"
android_clickable="true"
android_background="@color/colorAccent"
android_layout_marginTop="10dp"
android_textColor="@android:color/white"/>
</LinearLayout>
</LinearLayout>
(d). 모델.xml
이것은 RecyclerView 행 모델입니다. 이 레이아웃은 어댑터 클래스에서 확장됩니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="10dp"
card_view_cardCornerRadius="5dp"
card_view_cardElevation="5dp"
android_layout_height="200dp">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent">
<TextView
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Name"
android_id="@+id/nameTxt"
android_padding="10dp"
android_textColor="@color/colorAccent"
android_textStyle="bold"
android_layout_alignParentLeft="true"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
12. AndroidManifest.xml
- 매니페스트 파일에 인터넷 권한을 추가하는 것을 잊지 마십시오.
<사용 권한 android_name="android.permission.INTERNET"/>
다운로드
2. Android Firebase - RecyclerView 여러 필드
Android Firebase Database RecyclerView Tutorial 안드로이드 Firebase 데이터베이스 RecyclerView 튜토리얼입니다. Firebase에 데이터를 저장하는 방법은 사용자 정의 RecyclerView에서 해당 데이터를 검색한 다음 표시합니다.
이번에는 이전 예에서와 같이 단일 필드가 아닌 여러 필드를 사용합니다.
1. 설정
(ㅏ). 기본 활동 프로젝트 만들기
- 먼저 안드로이드 스튜디오에서 새 프로젝트를 생성합니다. 파일 --> 새 프로젝트로 이동합니다.
(b).Firebase 생성 및 구성 파일 다운로드
Firebase 콘솔로 이동하여 Firebase 앱을 만들고 앱 ID를 등록하고 google-services.json
파일을 다운로드합니다. 앱 폴더에 추가합니다.
(씨). Maven 저장소 URL 지정
프로젝트 수준(프로젝트 폴더) build.gradle
로 이동하고
- 아래와 같이 Google 서비스 클래스 경로를 추가합니다.
- maven 저장소 URL 추가
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
(d). Firebase 종속성 추가
앱 수준(앱 폴더) build.gradle
에 추가한 다음
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:cardview-v7:23.3.0'
compile 'com.google.firebase:firebase-core:11.8.0'
compile 'com.google.firebase:firebase-database:11.8.0'
}
apply plugin: 'com.google.gms.google-services'
위와 같이 '플러그인 적용: 'com.google.gms.google-services''를 확인하세요.
(e). 안드로이드 매니페스트
- 매니페스트 파일에 인터넷 권한을 추가하는 것을 잊지 마십시오.
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.tutorials.hp.firebaserecyclermulti_items">
<uses-permission android_name="android.permission.INTERNET"/>
....
</manifest>
2. 클래스
(ㅏ). 우리의 모델 클래스
- 우리의 데이터 객체 클래스인가
- 빈 생성자가 있어야 합니다.
- 다른 생성자에 데이터를 생성, 전달 및 사용할 수 있습니다.
package com.tutorials.hp.firebaserecyclermulti_items.m_Model;
/*
* 1. OUR MODEL CLASS
*/
public class Spacecraft {
String name,propellant,description;
public Spacecraft() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPropellant() {
return propellant;
}
public void setPropellant(String propellant) {
this.propellant = propellant;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
(b). FirebaseHelper 클래스
- 기본적으로 CRUD 클래스입니다.
- 여기에서 Firebase 데이터베이스에 대한 읽기 및 쓰기를 수행합니다.
- 데이터를 유지하기 위해 setValue()를 사용합니다.
- setValue() 메서드를 호출하기 전에 push()를 호출하여 교체가 아닌 데이터베이스에 데이터를 추가하도록 합니다.
- 모델 객체로 arraylist를 채웁니다.
package com.tutorials.hp.firebaserecyclermulti_items.m_FireBase;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.tutorials.hp.firebaserecyclermulti_items.m_Model.Spacecraft;
import java.util.ArrayList;
/*
* 1. RECEIVE DB REFERENCE
* 2. SAVE
* 3. RETRIEVE
* 4. RETURN ARRAYLIST
*/
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
ArrayList<Spacecraft> spacecrafts=new ArrayList<>();
/*
PASS DATABASE REFRENCE
*/
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Spacecraft spacecraft)
{
if(spacecraft==null)
{
saved=false;
}else
{
try
{
db.child("Spacecraft").push().setValue(spacecraft);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Spacecraft spacecraft=ds.getValue(Spacecraft.class);
spacecrafts.add(spacecraft);
}
}
//READ BY HOOKING ONTO DATABASE OPERATION CALLBACKS
public ArrayList<Spacecraft> retrieve()
{
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return spacecrafts;
}
}
(씨). ViewHolder 클래스
- 우리가 재활용할 수 있는 견해를 가지고 있습니다.
- 하위 클래스 RecyclerView.ViewHolder
package com.tutorials.hp.firebaserecyclermulti_items.m_UI;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.tutorials.hp.firebaserecyclermulti_items.R;
/*
* 1. HOLD VIEWS
*/
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView nameTxt,propTxt,descTxt;
public MyViewHolder(View itemView) {
super(itemView);
nameTxt=(TextView) itemView.findViewById(R.id.nameTxt);
propTxt=(TextView) itemView.findViewById(R.id.propellantTxt);
descTxt=(TextView) itemView.findViewById(R.id.descTxt);
}
}
9. MyAdapter 클래스
- 레이아웃 인플레이션을 담당합니다.
- 뷰에 대한 데이터 바인딩에도 사용됩니다.
- 이 클래스는 RecyclerView.Adapter의 하위 클래스입니다.
package com.tutorials.hp.firebaserecyclermulti_items.m_UI;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tutorials.hp.firebaserecyclermulti_items.R;
import com.tutorials.hp.firebaserecyclermulti_items.m_Model.Spacecraft;
import java.util.ArrayList;
/
* 1. LAYOUT INFLATION
* 2. RECEIVE SPACECRAFTS
* 3. PERFORM BINDING
*/
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<Spacecraft> spacecrafts;
public MyAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.nameTxt.setText(spacecrafts.get(position).getName());
holder.propTxt.setText(spacecrafts.get(position).getPropellant());
holder.descTxt.setText(spacecrafts.get(position).getDescription());
}
@Override
public int getItemCount() {
return spacecrafts.size();
}
}
(d). 우리의 주요 활동
- 실행기 활동.
- RecyclerView를 참조하고 LayoutManager를 설정합니다.
- 어댑터를 설정합니다.
- FAB 버튼 클릭 시 입력 대화 상자를 표시합니다.
- DatabaseReference를 초기화하여 Firebase를 설정합니다.
package com.tutorials.hp.firebaserecyclermulti_items;
import android.app.Dialog;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebaserecyclermulti_items.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebaserecyclermulti_items.m_Model.Spacecraft;
import com.tutorials.hp.firebaserecyclermulti_items.m_UI.MyAdapter;
/*
1.INITIALIZE FIREBASE DB
2.INITIALIZE UI
3.DATA*/
public class MainActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper helper;
MyAdapter adapter;
RecyclerView rv;
EditText nameEditTxt,propTxt,descTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//INITIALIZE RV
rv= (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
//INITIALIZE FB
db= FirebaseDatabase.getInstance().getReference();
helper=new FirebaseHelper(db);
//ADAPTER
adapter=new MyAdapter(this,helper.retrieve());
rv.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
displayInputDialog();
}
});
}
//DISPLAY INPUT DIALOG
private void displayInputDialog()
{
//CREATE DIALOG
Dialog d=new Dialog(this);
d.setTitle("Save To Firebase");
d.setContentView(R.layout.input_dialog);
nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
propTxt= (EditText) d.findViewById(R.id.propellantEditText);
descTxt= (EditText) d.findViewById(R.id.descEditText);
Button saveBtn= (Button) d.findViewById(R.id.saveBtn);
//SAVE
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//GET DATA
String name=nameEditTxt.getText().toString();
String propellant=propTxt.getText().toString();
String desc=descTxt.getText().toString();
//SET DATA
Spacecraft s=new Spacecraft();
s.setName(name);
s.setPropellant(propellant);
s.setDescription(desc);
//SAVE
if(name != null && name.length()>0)
{
if(helper.save(s))
{
nameEditTxt.setText("");
propTxt.setText("");
descTxt.setText("");
adapter=new MyAdapter(MainActivity.this,helper.retrieve());
rv.setAdapter(adapter);
}
}else
{
Toast.makeText(MainActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
}
}
});
d.show();
}
}
삼. 우리의 레이아웃
(ㅏ). InputDialog.xml
- 입력 대화 상자 레이아웃을 정의합니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="15dp"
android_paddingRight="15dp"
android_paddingTop="50dp">
<android.support.design.widget.TextInputLayout
android_id="@+id/nameLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/nameEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Name" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android_id="@+id/propLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/propellantEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Propellant" />
<android.support.design.widget.TextInputLayout
android_id="@+id/descLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/descEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Description" />
</android.support.design.widget.TextInputLayout>
</android.support.design.widget.TextInputLayout>
<Button android_id="@+id/saveBtn"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Save"
android_clickable="true"
android_background="@color/colorAccent"
android_layout_marginTop="40dp"
android_textColor="@android:color/white"/>
</LinearLayout>
</LinearLayout>
(b). 모델.xml
- 각 보기 항목이 표시되는 방식.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="10dp"
card_view_cardCornerRadius="5dp"
card_view_cardElevation="5dp"
android_layout_height="200dp">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent">
<TextView
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Name"
android_id="@+id/nameTxt"
android_padding="10dp"
android_textColor="@color/colorAccent"
android_textStyle="bold"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Description....................."
android_lines="3"
android_id="@+id/descTxt"
android_padding="10dp"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceMedium"
android_text="Propellant"
android_textStyle="italic"
android_id="@+id/propellantTxt" />
</LinearLayout>
</android.support.v7.widget.CardView>
4. 다운로드
삼. Android Firebase - RecyclerView 마스터 세부정보 [열기 활동]
안녕하세요, Android Firebase RecyclerView 마스터 세부 튜토리얼에 오신 것을 환영합니다.
이것은 안드로이드 Firebase 재활용 보기 튜토리얼입니다. Firebase에 데이터를 저장하는 방법은 사용자 정의 gridview에서 해당 데이터를 검색한 다음 표시합니다.
- edittext의 데이터를 Google Firebase 데이터베이스에 저장합니다.
- DatabaseReference 인스턴스에 이벤트를 첨부하여 데이터를 검색합니다.
- BaseAdapter 하위 클래스를 사용하여 데이터를 csutom gridview에 바인딩합니다.
- GridView의 itemClicks를 처리합니다.
- 그리드 항목을 클릭하면 새 활동이 열립니다.
- 새로운 활동에 데이터 전달
Firebase 실시간 데이터베이스란 무엇입니까?
Firebase 실시간 데이터베이스는 풍부한 앱을 빌드할 수 있는 플랫폼을 제공하는 서비스형 데이터베이스 백엔드 클라우드 호스팅 솔루션입니다. 일반적으로 우리는 서버에 대해 데이터를 읽거나 쓰기 위해 HTTP 요청을 하는 데 익숙합니다. 그러나 Firebase에서는 그렇지 않습니다. 동기화 기술을 사용합니다. 실시간이지만 여전히 성능이 좋습니다.
주요 기능?
- 실시간 .
- 플랫폼 독립.
- 쉬운 액세스 제어.
- NoSQL 솔루션이며 성능에 크게 최적화되어 있습니다.
- 오프라인 기능이 있습니다.
- 사용자 친화적입니다.
동영상 튜토리얼 자세한 설명은 아래 동영상 튜토리얼을 확인하세요.
설정
(a) .기본 활동 프로젝트 만들기
- 먼저 안드로이드 스튜디오에서 새 프로젝트를 생성합니다. 파일 --> 새 프로젝트로 이동합니다.
(b). Firebase 생성 및 구성 파일 다운로드
Firebase 콘솔로 이동하여 Firebase 앱을 만들고 앱 ID를 등록하고 google-services.json
파일을 다운로드합니다. 앱 폴더에 추가합니다.
(씨). Maven 저장소 URL 지정
프로젝트 수준(프로젝트 폴더) build.gradle
로 이동하고
- 아래와 같이 Google 서비스 클래스 경로를 추가합니다.
- maven 저장소 URL 추가
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
(d). Firebase 종속성 추가
앱 수준(앱 폴더) build.gradle에 추가한 다음
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:cardview-v7:23.3.0'
compile 'com.google.firebase:firebase-core:11.8.0'
compile 'com.google.firebase:firebase-database:11.8.0'
}
apply plugin: 'com.google.gms.google-services'
위와 같이 '플러그인 적용: 'com.google.gms.google-services''를 확인하세요.
(e). AndroidManifest.xml
- 매니페스트 파일에 인터넷 권한을 추가하는 것을 잊지 마십시오.
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.tutorials.hp.firebaserecyclermdetail">
<uses-permission android_name="android.permission.INTERNET"/>
<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_supportsRtl="true"
android_theme="@style/AppTheme">
<activity
android_name=".MainActivity"
android_label="@string/app_name"
android_theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android_name="android.intent.action.MAIN" />
<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android_name=".DetailActivity"
android_label="Detail View"
android_theme="@style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>
자바 클래스
(ㅏ). 우주선.자바
- 우리의 데이터 객체 클래스인가
- 빈 생성자가 있어야 합니다.
- 다른 생성자에 데이터를 생성, 전달 및 사용할 수 있습니다.
package com.tutorials.hp.firebaserecyclermdetail.m_Model;
/*
* 1. OUR MODEL CLASS
*/
public class Spacecraft {
String name,propellant,description;
public Spacecraft() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPropellant() {
return propellant;
}
public void setPropellant(String propellant) {
this.propellant = propellant;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
(b). FirebaseHelper.java
- 기본적으로 CRUD 클래스입니다.
- 여기에서 Firebase 데이터베이스에 대한 읽기 및 쓰기를 수행합니다.
- 데이터를 유지하기 위해 setValue()를 사용합니다.
- setValue() 메서드를 호출하기 전에 push()를 호출하여 교체가 아닌 데이터베이스에 데이터를 추가하도록 합니다.
- 우주선 객체로 arraylist를 채웁니다.
package com.tutorials.hp.firebaserecyclermdetail.m_FireBase;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.tutorials.hp.firebaserecyclermdetail.m_Model.Spacecraft;
import java.util.ArrayList;
/*
* 1.SAVE DATA TO FIREBASE
* 2. RETRIEVE
* 3.RETURN AN ARRAYLIST
*/
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
ArrayList<Spacecraft> spacecrafts=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Spacecraft spacecraft)
{
if(spacecraft==null)
{
saved=false;
}else
{
try
{
db.child("Spacecraft").push().setValue(spacecraft);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Spacecraft spacecraft=ds.getValue(Spacecraft.class);
spacecrafts.add(spacecraft);
}
}
//READ THEN RETURN ARRAYLIST
public ArrayList<Spacecraft> retrieve() {
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return spacecrafts;
}
}
(씨). 마이뷰홀더.자바
- 우리의 뷰홀더 클래스인가
- RecyclerView에 표시되는 뷰를 유지합니다.
package com.tutorials.hp.firebaserecyclermdetail.m_UI;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.tutorials.hp.firebaserecyclermdetail.R;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView nameTxt,propTxt,descTxt;
ItemClickListener itemClickListener;
public MyViewHolder(View itemView) {
super(itemView);
nameTxt= (TextView) itemView.findViewById(R.id.nameTxt);
propTxt= (TextView) itemView.findViewById(R.id.propellantTxt);
descTxt= (TextView) itemView.findViewById(R.id.descTxt);
itemView.setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener)
{
this.itemClickListener=itemClickListener;
}
@Override
public void onClick(View view) {
this.itemClickListener.onItemClick(this.getLayoutPosition());
}
}
(d). 마이어댑터.자바
- 레이아웃 인플레이션을 담당합니다.
- 뷰에 대한 데이터 바인딩에도 사용됩니다.
- 그런 다음 새 활동을 열고 android.Content.Intent를 통해 데이터를 전달합니다.
package com.tutorials.hp.firebaserecyclermdetail.m_UI;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.tutorials.hp.firebaserecyclermdetail.DetailActivity;
import com.tutorials.hp.firebaserecyclermdetail.R;
import com.tutorials.hp.firebaserecyclermdetail.m_Model.Spacecraft;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<Spacecraft> spacecrafts;
public MyAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Spacecraft s=spacecrafts.get(position);
holder.nameTxt.setText(s.getName());
holder.propTxt.setText(s.getPropellant());
holder.descTxt.setText(s.getDescription());
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(int pos) {
//OPEN DETAI ACTIVITY
openDetailActivity(s.getName(),s.getDescription(),s.getPropellant());
}
});
}
@Override
public int getItemCount() {
return spacecrafts.size();
}
//OPEN DETAIL ACTIVITY
private void openDetailActivity(String...details)
{
Intent i=new Intent(c,DetailActivity.class);
i.putExtra("NAME_KEY",details[0]);
i.putExtra("DESC_KEY",details[1]);
i.putExtra("PROP_KEY",details[2]);
c.startActivity(i);
}
}
(e). ItemClickListener.java
- onItemClick() 메서드에 대한 서명을 정의합니다.
package com.tutorials.hp.firebaserecyclermdetail.m_UI;
public interface ItemClickListener {
void onItemClick(int pos);
}
12. 메인 액티비티.자바
- 실행기 활동.
- RecyclerView를 참조하고 어댑터를 설정합니다.
- FAB 버튼 클릭 시 입력 대화 상자를 표시합니다.
- DatabaseReference를 초기화하여 Firebase를 설정합니다.
package com.tutorials.hp.firebaserecyclermdetail;
import android.app.Dialog;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.tutorials.hp.firebaserecyclermdetail.m_FireBase.FirebaseHelper;
import com.tutorials.hp.firebaserecyclermdetail.m_Model.Spacecraft;
import com.tutorials.hp.firebaserecyclermdetail.m_UI.MyAdapter;
/*
1.INITIALIZE FIREBASE DB
2.INITIALIZE UI
3.DATA INPUT
*/
public class MainActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper helper;
MyAdapter adapter;
RecyclerView rv;
EditText nameEditTxt,propTxt,descTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//SETUP RECYCLER
rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
//INITIALIZE FIREBASE DB
db= FirebaseDatabase.getInstance().getReference();
helper=new FirebaseHelper(db);
//ADAPTER
adapter=new MyAdapter(this,helper.retrieve());
rv.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
displayInputDialog();
}
});
}
//DISPLAY INPUT DIALOG
private void displayInputDialog()
{
Dialog d=new Dialog(this);
d.setTitle("Save To Firebase");
d.setContentView(R.layout.input_dialog);
nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
propTxt= (EditText) d.findViewById(R.id.propellantEditText);
descTxt= (EditText) d.findViewById(R.id.descEditText);
Button saveBtn= (Button) d.findViewById(R.id.saveBtn);
//SAVE
saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//GET DATA
String name=nameEditTxt.getText().toString();
String propellant=propTxt.getText().toString();
String desc=descTxt.getText().toString();
//SET DATA
Spacecraft s=new Spacecraft();
s.setName(name);
s.setPropellant(propellant);
s.setDescription(desc);
//SIMPLE VALIDATION
if(name != null && name.length()>0)
{
//THEN SAVE
if(helper.save(s))
{
//IF SAVED CLEAR EDITXT
nameEditTxt.setText("");
propTxt.setText("");
descTxt.setText("");
adapter=new MyAdapter(MainActivity.this,helper.retrieve());
rv.setAdapter(adapter);
}
}else
{
Toast.makeText(MainActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
}
}
});
d.show();
}
}
(f). DetailActivity.java
- 네, 여기에 세부 활동이 있습니다.우리의 세부 사항을 보여주기 위해.
- Intent를 통해 MainActivity에서 데이터를 수신합니다.
- TextViews에 데이터를 표시합니다.
package com.tutorials.hp.firebaserecyclermdetail;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
public class DetailActivity extends AppCompatActivity {
TextView nameTxt,descTxt, propTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
nameTxt = (TextView) findViewById(R.id.nameDetailTxt);
descTxt= (TextView) findViewById(R.id.descDetailTxt);
propTxt = (TextView) findViewById(R.id.propellantDetailTxt);
//GET INTENT
Intent i=this.getIntent();
//RECEIVE DATA
String name=i.getExtras().getString("NAME_KEY");
String desc=i.getExtras().getString("DESC_KEY");
String propellant=i.getExtras().getString("PROP_KEY");
//BIND DATA
nameTxt.setText(name);
descTxt.setText(desc);
propTxt.setText(propellant);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
레이아웃
(ㅏ). ActivityMain.xml
- ContentMain.xml이 포함되어 있습니다.
- Floating ActionButton을 정의합니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context="com.tutorials.hp.firebaserecyclermdetail.MainActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
(b). ContentMain.xml
- 우리의 마스터 뷰
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.firebaserecyclermdetail.MainActivity"
tools_showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android_id="@+id/rv"
android_layout_width="match_parent"
android_layout_height="wrap_content"
/>
</RelativeLayout>
(씨). inputdialog.xml
- 입력 대화 상자 레이아웃을 정의합니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical" android_layout_width="match_parent"
android_layout_height="match_parent">
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="15dp"
android_paddingRight="15dp"
android_paddingTop="50dp">
<android.support.design.widget.TextInputLayout
android_id="@+id/nameLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/nameEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Name" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android_id="@+id/propLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/propellantEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Propellant" />
<android.support.design.widget.TextInputLayout
android_id="@+id/descLayout"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<EditText
android_id="@+id/descEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_singleLine="true"
android_hint= "Description" />
</android.support.design.widget.TextInputLayout>
</android.support.design.widget.TextInputLayout>
<Button android_id="@+id/saveBtn"
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="Save"
android_clickable="true"
android_background="@color/colorAccent"
android_layout_marginTop="40dp"
android_textColor="@android:color/white"/>
</LinearLayout>
</LinearLayout>
(d). 모델.xml
- 사용자 지정 CardView를 정의합니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="10dp"
card_view_cardCornerRadius="5dp"
card_view_cardElevation="5dp"
android_layout_height="200dp">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent">
<TextView
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Name"
android_id="@+id/nameTxt"
android_padding="10dp"
android_textColor="@color/colorAccent"
android_textStyle="bold"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_text="Description....................."
android_lines="3"
android_id="@+id/descTxt"
android_padding="10dp"
android_layout_alignParentLeft="true"
/>
<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceMedium"
android_text="Propellant"
android_textStyle="italic"
android_id="@+id/propellantTxt" />
</LinearLayout>
</android.support.v7.widget.CardView>
(f). 활동_detail.xml
- ContentDetail.xml이 포함되어 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context="com.tutorials.hp.firebaserecyclermdetail.DetailActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_detail" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
(g). 내용_detail.xml
- 우리의 상세보기.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.firebaserecyclermdetail.DetailActivity"
tools_showIn="@layout/activity_detail">
<android.support.v7.widget.CardView
android_orientation="horizontal" android_layout_width="match_parent"
android_layout_margin="5dp"
card_view_cardCornerRadius="10dp"
card_view_cardElevation="5dp"
android_layout_height="match_parent">
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent"
android_weightSum="1">
<LinearLayout
android_orientation="horizontal"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<ImageView
android_id="@+id/articleDetailImg"
android_layout_width="320dp"
android_layout_height="wrap_content"
android_paddingLeft="10dp"
android_layout_alignParentTop="true"
android_scaleType="centerCrop"
android_src="@drawable/spitzer" />
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="wrap_content">
<TextView
android_id="@+id/nameDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_padding="5dp"
android_minLines="1"
android_textStyle="bold"
android_textColor="@color/colorAccent"
android_text="Title" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android_layout_width="fill_parent"
android_layout_height="match_parent"
android_layout_marginTop="?attr/actionBarSize"
android_orientation="vertical"
android_paddingLeft="5dp"
android_paddingRight="5dp"
android_paddingTop="5dp">
<TextView
android_id="@+id/propellantDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_padding="5dp"
android_minLines="1"
android_text="DATE" />
<TextView
android_id="@+id/descDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceLarge"
android_padding="5dp"
android_textColor="#0f0f0f"
android_minLines="4"
android_text="Space craft details...." />
<TextView
android_id="@+id/linkDetailTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_textAppearance="?android:attr/textAppearanceMedium"
android_padding="5dp"
android_textColor="@color/colorPrimaryDark"
android_textStyle="italic"
android_text="Link" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
4. 다운로드
실행 방법
- 프로젝트를 다운로드합니다.
- 압축된 파일을 얻을 것입니다. 압축을 풉니다.
- 안드로이드 스튜디오를 엽니다.
- 이제 프로젝트를 닫고 이미 열려 있습니다.
- 메뉴 모음에서 파일 > 새로 만들기 > 프로젝트 가져오기를 클릭합니다.
- 이제 프로젝트를 가져올 대상 폴더를 선택합니다.
- Android 프로젝트를 선택합니다.
- 이제 "확인"을 클릭합니다.
- 프로젝트 가져오기를 완료했습니다. 이제 편집합니다.
- Firebase 콘솔로 이동하여 앱을 만든 다음 구성 파일을 다운로드하고 앱 폴더의 프로젝트에 추가해야 합니다.