✍2021,2022/app(android studio)

앱만들기 11.(RecyclerView)

리촬리 2021. 7. 13. 15:29
728x90

gradle(app)설정

gradle->dependencies 마우스 올려놓으면 전구 뜸

->add library ~ 클릭 -> recyclerview 라이브러리 누름

-> appocompat과 버전 동일해야 오류 안남 ->sync now클릭

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.recyclerviewexample"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

item.xml

 

recycle view로 인해 item list가 화면에 보임

이 item들을 설정해주기 위해 item.xml만듦

사진영역만큼의 틀을 만들기 위해

linear안의 imageview에 linear를 해줌 

android:gravity="center_vertical" : 세로 가운데 정렬 ( 세로로 정렬되어있으면서 가운데로 )

최상위 부모 linear 레이아웃에서 가로는 화면에 꽉 차게 match이지만, 세로는 저 이미지 틀에 맞춰서 wrap으로

android:layout_width="match_parent"
android:layout_height="wrap_content"

 

총 3개의 id값 지정

imageview => id : iv_profile

textview => id:tv_name

textview => id: tv_content

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/iv_profile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:orientation="vertical"
            >
            <TextView
                android:id="@+id/tv_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="이름"/>
            <TextView
                android:id="@+id/tv_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="리사이클러 뷰"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

maindata.java ( item.xml에 대응되는 java)

Maindata.java만들어줌

image view는 int값임

 

alt+insert 에서 constructor 눌러서 구조 만들어줌

다 선택해서 ok해줌

다음과같은 구조 만들어짐

public Maindata(int iv_profile, String tv_name, String tv_content) {
this.iv_profile = iv_profile;
this.tv_name = tv_name;
this.tv_content = tv_content;
}

 

alt +insert 다시 해서

getter and setter클릭 해서 또 다 추가

public int getIv_profile() {
return iv_profile;
}

public void setIv_profile(int iv_profile) {
this.iv_profile = iv_profile;
}

public String getTv_name() {
return tv_name;
}

public void setTv_name(String tv_name) {
this.tv_name = tv_name;
}

public String getTv_content() {
return tv_content;
}

public void setTv_content(String tv_content) {
this.tv_content = tv_content;
}

이렇게 뜸

 

지금 설정한 constructor와

getter 와 setter가 뭔지 알아보기

package com.example.recyclerviewexample;

public class Maindata {

    private int iv_profile;
    private String tv_name;
    private String tv_content;

    public Maindata(int iv_profile, String tv_name, String tv_content) {
        this.iv_profile = iv_profile;
        this.tv_name = tv_name;
        this.tv_content = tv_content;
    }

    public int getIv_profile() {
        return iv_profile;
    }

    public void setIv_profile(int iv_profile) {
        this.iv_profile = iv_profile;
    }

    public String getTv_name() {
        return tv_name;
    }

    public void setTv_name(String tv_name) {
        this.tv_name = tv_name;
    }

    public String getTv_content() {
        return tv_content;
    }

    public void setTv_content(String tv_content) {
        this.tv_content = tv_content;
    }
}

Mainadapter.java 생성

public class Mainadapter extends RecyclerView.Adapter<Mainadapter.CustomViewHolder> {

해주고 오류뜨는 CustomViewHolder 에서 implement methods 하면

나오는거 추가하면 구현이됨

여전히 에러뜨는 CustomViewHoler 의 클래스 생성해주고 (alt+enter)

 

//listview item들을 담을 배열리스트만들기
private ArrayList<Maindata> arrayList;

ALT+INSERT사용해서 constructor
public Mainadapter(ArrayList<Maindata> arrayList) {
this.arrayList = arrayList;
}

@NonNull
@org.jetbrains.annotations.NotNull

 

리스트 뷰 메뉴가 처음 생성될때 생명주기
@Override
public Mainadapter.CustomViewHolder onCreateViewHolder(@NonNull @org.jetbrains.annotations.NotNull ViewGroup parent, int viewType) {
return null;
}

 

//실제 추가될때에 대한 생명주기
@Override
public void onBindViewHolder(@NonNull Mainadapter.CustomViewHolder holder, int position) {
holder.iv_profile.setImageResource(arrayList.get(position).getIv_profile());
holder.tv_name.setText(arrayList.get(position).getTv_name());
holder.tv_content.setText(arrayList.get(position).getTv_content());
//클릭이 되었을때 구현되는거
holder.itemView.setTag(position);
holder.itemView.setOnClickListener(new View.OnClickListener() {

클릭했을때 recycleView item중에 클릭한 것의 이름을 가져옴

@Override
public void onClick(View v) {

String curName = holder.tv_name.getText().toString()

현재 이름값은 = tvname으로부터 gettext해와라 => 오브젝트 형태이기 때문에 toString()을 붙여줘서 스트링값으로 변환

Toast.makeText(v.getContext(),curName,Toast.LENGTH_SHORT).show();

리스트 뷰 클릭했을때 컬 네임이 토스트 메뉴로 lengthshort방식으로 출력이 됨


}
});
}

 

longclick을 눌렀을때 리스트 뷰를 삭제하는 예제

 

public void remove(int position){
//예외상황 벌어졌을대 강제실행해주는 역할할
try{
arrayList.remove(position);
notifyItemRemoved(position);
//notify == 새로고침 이라는 뜻
}catch(IndexOutOfBoundsException ex){
ex.printStackTrace();
}

}

 

holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
remove(holder.getAdapterPosition());
return true;
}
});

package com.example.recyclerviewexample;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class Mainadapter extends RecyclerView.Adapter<Mainadapter.CustomViewHolder> {
//listview의 item들을 담을 배열리스트만들기
    private ArrayList<Maindata> arrayList;

    public Mainadapter(ArrayList<Maindata> arrayList) {
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public Mainadapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list,parent);
        CustomViewHolder holder =new CustomViewHolder(view);

        return holder;
    }

//실제 추가될때에 대한 생명주기
    @Override
    public void onBindViewHolder(@NonNull final Mainadapter.CustomViewHolder holder, int position) {
        holder.iv_profile.setImageResource(arrayList.get(position).getIv_profile());
        holder.tv_name.setText(arrayList.get(position).getTv_name());
        holder.tv_content.setText(arrayList.get(position).getTv_content());
        //클릭이 되었을때 구현되는거
        holder.itemView.setTag(position);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String curName = holder.tv_name.getText().toString();
                Toast.makeText(v.getContext(),curName,Toast.LENGTH_SHORT).show();
            }
        });
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                remove(holder.getAbsoluteAdapterPosition());
                return true;
            }
        });
    }

    @Override
    public int getItemCount() {
        return (null != arrayList ? arrayList.size():0);
    }

    public void remove(int position){
        //예외상황 벌어졌을대 강제실행해주는 역할할
       try{
            arrayList.remove(position);
            notifyItemRemoved(position);
            //notify == 새로고침 이라는 뜻
        }catch(IndexOutOfBoundsException ex){
            ex.printStackTrace();
        }

    }

    public class CustomViewHolder extends RecyclerView.ViewHolder {

        protected ImageView iv_profile;
        protected TextView tv_name;
        protected TextView tv_content;

        public CustomViewHolder(View itemView) {
            super(itemView);
            this.iv_profile = (ImageView) itemView.findViewById(R.id.iv_profile);
            this.tv_name = (TextView) itemView.findViewById(R.id.tv_name);
            this.tv_content = (TextView) itemView.findViewById(R.id.tv_content);

        }
    }
}

추가버튼을 눌렀을때 추가가 되는기능 구현 

mainactivity.java

package com.example.recyclerviewexample;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private ArrayList<Maindata> arraylist;
    private Mainadapter mainadapter;
    private RecyclerView recyclerView;
    private LinearLayoutManager linearLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = (RecyclerView)findViewById(R.id.rv);
        linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        arraylist = new ArrayList<>();
        //아까 만든 mainadapter를 arraylist에 넣어줌
        mainadapter = new Mainadapter(arraylist);
        //담긴거를 리사이클 뷰에 세팅해줘라
        recyclerView.setAdapter(mainadapter);

        Button btn_add = (Button)findViewById(R.id.btn_add);
        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Maindata maindata = new Maindata(R.mipmap.ic_launcher,"울랄라","리사이클러뷰");
                arraylist.add(maindata);
                mainadapter.notifyDataSetChanged();
                //새로고침

            }
        });

    }
}

결과

앱이 자꾸 튕김 왜이러냐아아악 짜증나네 ..

귀찮으니 해결법은 찾지않음..

728x90