안드로이드 개발 Recyclerview 사용법
- 안드로이드 개발/firebase database 사용 어플 만들기
- 2018. 12. 13. 22:34
database 목록을 가져오기 위해서는 꼭 필요한 게 뭘까요?
바로 ListView 입니다. 서버(firebase database)에 있는 목록을 리스트뷰로 뿌려줘야합니다.
저는 ListView 대신 RecyclerView를 사용하려고 합니다.
RecyclerView란 한마디로 말하자면 ListView의 업그레이드 버젼이라고 생각하면 됩니다.
리사이클러뷰의 자세한 내용은 안드로이드 디벨로퍼 공식 홈에서 확인할 수 있어요.
저희가 RecyclerView 만드려고 하는 최종 화면입니다. 굉장히 간단한 뷰인데요.
여기에 사진도 넣고, 제목, 날짜도 보일 수 있도록 다양한 방법으로 꾸밀 수도 있어요.
아직 초보단계이기 때문에, 기본적인 리스트뷰를 만들어볼게요.
Build.gradle에 따로 추가하지 않아도 가능합니다. 만약에 오류가 뜬다면 dependencies에 아래 코드를 넣어주세요.
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
뒤에 있는 버전은 개발환경에 따라 다르게 설정해야할 수도 있습니다.
리사이클러뷰의 코드는 아래와 같습니다. 이것을 구현하고자하는 xml에 추가합니다.
list.xml
<android.support.v7.widget.RecyclerView android:id="@+id/list_recyclerview" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView>
리스트뷰와 별 차이 없이 굉장히 간단합니다. 이제 이 RecyclerView의 item 하나하나의 디자인을 설정해줄 xml이 필요합니다. list_item.xml로 하나 만들어보겠습니다.
list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/chat_message_item_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/list_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginLeft="20dp"
android:layout_marginBottom="15dp"
android:text="메시지"
android:textSize="15sp"
android:textColor="@color/colorPrimaryDark"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/line_color" />
</LinearLayout>
list_item.xml은 심플할수도 있고 복잡할수도 있습니다. 저 같은 경우에는 TextView만 보여지도록 했지만, 사용자에 따라서 텍스트뷰, 이미지뷰 등등 여러가지 뷰로 구성해야하기 때문에 디자인측면에서 중요한 xml이라고 생각이 드네요. 원하는 디자인으로 예쁘게 꾸며보세요^^
다음은 ListActivity.java의 코드를 한번 살펴보겠습니다.
RecyclerView를 선언하고 Layoutmanager 와 Adapter를 만들어줍니다.
list_recyclerview = (RecyclerView) findViewById(R.id.list_recyclerview);
list_recyclerview.setLayoutManager(new LinearLayoutManager(ListActivity.this));
int child_case = 0;
list_recyclerview.setAdapter(new RecyclerViewAdapter(child_case));
그리고 RecyclerViewAdapter.class를 만들어줍니다.
class RecyclerViewAdapter extends RecyclerView.Adapter{
//아래부분 static class 불러옴
List contents;
public RecyclerViewAdapter(int child_case) {
contents = new ArrayList<>();
FirebaseDatabase.getInstance().getReference().child("article").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
contents.clear();
for(DataSnapshot item : dataSnapshot.getChildren()){
contents.add(item.getValue(Article.articledata.class));
}
//메시지 갱신 위치
notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new MessageVieHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
MessageVieHolder messageVieHolder = ((MessageVieHolder)holder);
//레이아웃
messageVieHolder.list_title.setText(contents.get(position).title);
final String list_url = contents.get(position).url;
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Intent intent = new Intent(Info_Notice.this, Info_PopupActivity.class);
Intent intent = new Intent(ListActivity.this, WebViewActivity.class);
intent.putExtra("url", list_url);
startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return contents.size();
}
private class MessageVieHolder extends RecyclerView.ViewHolder {
public TextView list_title;
public MessageVieHolder(View view) {
super(view);
list_title = view.findViewById(R.id.list_title);
}
}
}
바로 아래에 Article.class를 만들어 줍니다.
public static class Article {
public Map article_data = new HashMap<>();
public static class articledata {
public String title;
public String url;
}
}
이제, RecyclerView의 아이템을 클릭 했을 때 넘어가는 WebView를 만들어주겠습니다. 웹뷰를 안 만들고 바로 외부 어플로 연동시키는 방법도 있지만 여기서는 웹뷰를 이용하는 방법으로 해보겠습니다.
웹뷰는 이전에 만든 어플에서 사용하던 것을 그대로 가져왔습니다.
이전, 닫기, 다음 버튼이 있는 웹뷰입니다 ^^
WebViewActivity.java
package com.tistory.hamzzibari.upload_firebase;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
public class WebViewActivity extends AppCompatActivity {
WebView webView;
String url;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
getWindow().setWindowAnimations(android.R.style.Animation_Toast);
//intent 받아오기
Intent intent = getIntent();
url = intent.getExtras().getString("url");
webView = (WebView) findViewById(R.id.webview);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(false);
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
settings.setDomStorageEnabled(true);
settings.setAppCacheEnabled(true);
webView.requestFocus(View.FOCUS_DOWN);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setScrollbarFadingEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
// webView.setWebViewClient(new WebViewClient()); // 새로운 창을 띄우지 않고 내부에서 웹뷰를 실행시킨다.
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getScheme().equals("market")) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
Activity host = (Activity) view.getContext();
host.startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
// Google Play app is not installed, you may want to open the app store link
Uri uri = Uri.parse(url);
view.loadUrl("http://play.google.com/store/apps/" + uri.getHost() + "?" + uri.getQuery());
return false;
}
}
return false;
}
});
webView.loadUrl(url);
//뒤로
final Button button_back = (Button) findViewById(R.id.button_back);
button_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (webView.canGoBack()) {
webView.goBack();
}
}
});
//앞으로
final Button button_forward = (Button) findViewById(R.id.button_forward);
button_forward.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (webView.canGoForward()) {
webView.goForward();
}
}
});
//닫기 버튼
final Button button_cancel = (Button) findViewById(R.id.button_cancel);
button_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (webView.canGoBack()) {
webView.goBack();
} else {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}
webview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<WebView
android:id="@+id/webview"
android:layout_above="@id/linearLayout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="WebViewLayout" />
<LinearLayout
android:id="@+id/linearLayout_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:weightSum="3">
<Button
android:id="@+id/button_back"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="⟪"
android:textSize="15sp"
android:textColor="@color/blue"
android:textStyle="bold"
android:layout_weight="1"
android:theme="@style/MyButton" />
<Button
android:id="@+id/button_cancel"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="닫기"
android:textColor="@color/blue"
android:textStyle="bold"
android:layout_weight="1"
android:theme="@style/MyButton" />
<Button
android:id="@+id/button_forward"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="⟫"
android:textSize="15sp"
android:textColor="@color/blue"
android:textStyle="bold"
android:layout_weight="1"
android:theme="@style/MyButton" />
</LinearLayout>
</RelativeLayout>
RecyclerView 완성!!!^^
'안드로이드 개발 > firebase database 사용 어플 만들기' 카테고리의 다른 글
안드로이드 RecyclerView 무한스크롤, load more 방법 (3) | 2019.01.12 |
---|---|
안드로이드 RecyclerView에서 firebase database 역순 정렬 방법 (0) | 2019.01.12 |
[안드로이드 앱 만들기] firebase의 database 어플 #7(toolbar) (0) | 2018.12.13 |
[안드로이드 앱 만들기] firebase의 database 어플 #6(firebase upload) (3) | 2018.12.10 |
android studio firebase 연동 방법 (0) | 2018.12.09 |