Android

Json (์ œ์ด์Šจ) ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑํ•˜๊ณ  ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ

567Rabbit 2024. 6. 10. 16:41

 

 

activity_main.xml ์ž‘์„ฑํ•˜๊ธฐ

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/btnAdd"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerInParent="false"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginBottom="10dp"
            android:text="์ง์› ์ถ”๊ฐ€"
            android:textSize="30sp" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/btnAdd" />

        <ProgressBar
            android:id="@+id/progressBar2"
            style="?android:attr/progressBarStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/btnAdd"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="316dp"
            android:visibility="visible" />

    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

 

JSON ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  RecyclerView๋กœ ํ‘œ์‹œํ•˜๋Š” ๊ณผ์ •

 

  1. JSON ๋ฐ์ดํ„ฐ ์ˆ˜์‹  ๋ฐ ํŒŒ์‹ฑ : ์„œ๋ฒ„์—์„œ JSON ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ , ํŒŒ์‹ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Gson, Jackson ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JSON ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ        Java ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
  2. ์–ด๋Œ‘ํ„ฐ ์ƒ์„ฑ : RecyclerView.Adapter๋ฅผ ํ™•์žฅํ•˜์—ฌ ์ปค์Šคํ…€ ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ์–ด๋Œ‘ํ„ฐ ๋‚ด์—์„œ ViewHolder ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•œ ํ›„, onBindViewHolder ๋ฉ”์„œ๋“œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ทฐ์— ๋ฐ”์ธ๋”ฉ
  3. RecyclerView ์„ค์ • : RecyclerView์— ๋ ˆ์ด์•„์›ƒ ๋งค๋‹ˆ์ €๋ฅผ ์„ค์ •(์˜ˆ: LinearLayoutManager, GridLayoutManager ๋“ฑ) ํ›„ RecyclerView์— ์–ด๋Œ‘ํ„ฐ๋ฅผ ์„ค์ •

 

 

 

Json ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑํ•˜๊ณ , ์–ด๋Œ‘ํ„ฐ(adapter) ์‚ฌ์šฉํ•˜์—ฌ RecyclerView๋กœ ๋งŒ๋“ค๊ธฐ

 

 

JSON ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑํ•˜๊ธฐ?

= ์ œ์ด์Šจ์œผ๋กœ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด์™€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.  try ์•ˆ์—์„œ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•œ๋‹ค.

 

 

RecyclerView๋Š” Android์—์„œ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•œ ๋ทฐ์ด๋‹ค. RecyclerView๋Š” ์Šคํฌ๋กค ์‹œ ๋ทฐ๋ฅผ ์žฌ์‚ฌ์šฉ(recycle)ํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ค„์ด๊ณ , ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค. ๋˜ํ•œ ๋‹ค์–‘ํ•œ ๋ ˆ์ด์•„์›ƒ ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ๋ฆฌ์ŠคํŠธ, ๊ทธ๋ฆฌ๋“œ, ์Šคํƒœ๊ฑฐ๋“œ ๋ ˆ์ด์•„์›ƒ ๋“ฑ์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง€์› ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.

 

 

์–ด๋Œ‘ํ„ฐ(Adapter)๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค(์˜ˆ: JSON ๋ฐ์ดํ„ฐ)์™€ RecyclerView๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ ํ•ญ๋ชฉ์„ ๊ฐœ๋ณ„ ๋ทฐ ํ™€๋”(ViewHolder)์™€ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ RecyclerView์— ํ‘œ์‹œํ•œ๋‹ค.

 

 

 

 

 

๋จผ์ € ์ด ๋ฐ์ดํ„ฐ๋ฅผ,

{"status":"success","data":[{"id":1,"employee_name":"Tiger Nixon","employee_salary":320800,"employee_age":61,"profile_image":""},{"id":2,"employee_name":"Garrett Winters","employee_salary":170750,"employee_age":63,"profile_image":""},{"id":3,"employee_name":"Ashton Cox","employee_salary":86000,"employee_age":66,"profile_image":""},{"id":4,"employee_name":"Cedric Kelly","employee_salary":433060,"employee_age":22,"profile_image":""},{"id":5,"employee_name":"Airi Satou","employee_salary":162700,"employee_age":33,"profile_image":""},{"id":6,"employee_name":"Brielle Williamson","employee_salary":372000,"employee_age":61,"profile_image":""},{"id":7,"employee_name":"Herrod Chandler","employee_salary":137500,"employee_age":59,"profile_image":""},{"id":8,"employee_name":"Rhona Davidson","employee_salary":327900,"employee_age":55,"profile_image":""},{"id":9,"employee_name":"Colleen Hurst","employee_salary":205500,"employee_age":39,"profile_image":""},{"id":10,"employee_name":"Sonya Frost","employee_salary":103600,"employee_age":23,"profile_image":""},{"id":11,"employee_name":"Jena Gaines","employee_salary":90560,"employee_age":30,"profile_image":""},{"id":12,"employee_name":"Quinn Flynn","employee_salary":342000,"employee_age":22,"profile_image":""},{"id":13,"employee_name":"Charde Marshall","employee_salary":470600,"employee_age":36,"profile_image":""},{"id":14,"employee_name":"Haley Kennedy","employee_salary":313500,"employee_age":43,"profile_image":""},{"id":15,"employee_name":"Tatyana Fitzpatrick","employee_salary":385750,"employee_age":19,"profile_image":""},{"id":16,"employee_name":"Michael Silva","employee_salary":198500,"employee_age":66,"profile_image":""},{"id":17,"employee_name":"Paul Byrd","employee_salary":725000,"employee_age":64,"profile_image":""},{"id":18,"employee_name":"Gloria Little","employee_salary":237500,"employee_age":59,"profile_image":""},{"id":19,"employee_name":"Bradley Greer","employee_salary":132000,"employee_age":41,"profile_image":""},{"id":20,"employee_name":"Dai Rios","employee_salary":217500,"employee_age":35,"profile_image":""},{"id":21,"employee_name":"Jenette Caldwell","employee_salary":345000,"employee_age":30,"profile_image":""},{"id":22,"employee_name":"Yuri Berry","employee_salary":675000,"employee_age":40,"profile_image":""},{"id":23,"employee_name":"Caesar Vance","employee_salary":106450,"employee_age":21,"profile_image":""},{"id":24,"employee_name":"Doris Wilder","employee_salary":85600,"employee_age":23,"profile_image":""}],"message":"Successfully! All records has been fetched."}

 

 

 

์ด ์ฐฝ์„ ์—ด์–ด ๋„ฃ์€ ํ›„, copy๋ฅผ ๋ˆŒ๋Ÿฌ์ค€๋‹ค.

 

https://jsoneditoronline.org/#left=local.tusimo&right=local.qofoce

 

JSON Editor Online: edit JSON, format JSON, query JSON

JSON Editor Online is the original and most copied JSON Editor on the web. Use it to view, edit, format, repair, compare, query, transform, validate, and share your JSON data.

jsoneditoronline.org

 

 

 

 

์ค‘๊ด„ํ˜ธ {} ๋Š” object ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‹ค.

๋Œ€๊ด„ํ˜ธ []๋Š” array ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‹ค.

 

 

 


Adapter.java ํด๋ž˜์Šค

 

(EmployeeAdapter.java๋กœ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.)

package com.~.employee.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

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

import com.~.employee.R;
import com.~.employee.model.Employer;

import java.text.DecimalFormat;
import java.util.ArrayList;

public class EmployerAdapter extends RecyclerView.Adapter<EmployerAdapter.ViewHolder> {

    Context context;
    ArrayList<Employer> employerArrayList;

    public EmployerAdapter(Context context, ArrayList<Employer> employerArrayList) {
        this.context = context;
        this.employerArrayList = employerArrayList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.employer_row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Employer employer = employerArrayList.get(position);
        holder.txtName.setText(employer.name);
        holder.txtAge.setText(String.valueOf("๋‚˜์ด : "+employer.age+"์„ธ"));

        DecimalFormat formatter = new DecimalFormat("#,###");
        String strSalary = formatter.format(employer.salary);
        holder.txtSalary.setText(String.valueOf("์—ฐ๋ด‰ : $"+strSalary));
    }

    @Override
    public int getItemCount() {
        return employerArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView txtName;
        TextView txtAge;
        TextView txtSalary;
        ImageView imgDelete;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txtName = itemView.findViewById(R.id.txtName);
            txtAge = itemView.findViewById(R.id.txtAge);
            txtSalary = itemView.findViewById(R.id.txtSalary);
            imgDelete = itemView.findViewById(R.id.imgDelete);
        }
    }
}

 

 

 

 

MainActivity.java ํด๋ž˜์Šค (ํŒŒ์‹ฑํ•˜๊ธฐ)

package com.~.employee;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

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

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.yujinoh.employee.adapter.EmployerAdapter;
import com.yujinoh.employee.model.Employer;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Button btnAdd;
    ProgressBar progressBar;
    EmployerAdapter adapter;

    //๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ๋Š” ๊ด€๋ จ๋œ ๋ฉค๋ฒ„๋ณ€์ˆ˜ 2๊ฐœ ๋” ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค
    RecyclerView recyclerView;
    ArrayList<Employer> employerArrayList = new ArrayList<>();


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

        //๋‹ค์Œ ์ฝ”๋“œ๋Š” ์Œ์œผ๋กœ ๋ฌด์กฐ๊ฑด ๊ฐ™์ด ์ž‘์„ฑ
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

        btnAdd = findViewById(R.id.btnAdd);
        progressBar = findViewById(R.id.progressBar2);
        recyclerView = findViewById(R.id.recyclerView);

        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // AddActivity๋ฅผ ๋„์šด๋‹ค
                Intent intent = new Intent(MainActivity.this, AddActivity.class);
                startActivity(intent);
            }
        });

        // ๋„คํŠธ์›Œํฌ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜จ๋‹ค
        // Volley ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•œ ๋„คํŠธ์›Œํฌ ํ†ต์‹ 

        // 1. request queue ๋ฅผ ๋งŒ๋“ ๋‹ค
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);

        // 2. request(์š”์ฒญ)์„ ๋งŒ๋“ ๋‹ค.
        // ๋ฐ์ดํ„ฐ ํƒ€์ž…์€, ์‘๋‹ต์˜ json ํ˜•์‹์„ ๋ณด๊ณ  ๊ฒฐ์ •ํ•œ๋‹ค.
        JsonObjectRequest request = new JsonObjectRequest(
                Request.Method.GET,
                "https://block1-image-test.s3.ap-northeast-2.amazonaws.com/employees.json",
                null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        // ํ”„๋กœ๊ทธ๋ ˆ์Šค ๋ฐ”๋ฅผ ์œ ์ €์˜ ๋ˆˆ์—์„œ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•˜๋Š” ์ฝ”๋“œ
                        progressBar.setVisibility(View.GONE);

                        Log.i("EMPLOYEE MAIN", response.toString());

                        try {
                            String status = response.getString("status");
                            if(status.equals("success") == false){
                                Toast.makeText(MainActivity.this,
                                        "๋„คํŠธ์›Œํฌ ์—๋Ÿฌ",
                                        Toast.LENGTH_SHORT).show();
                                return;
                            }

                            JSONArray data = response.getJSONArray("data");

                            for(int i = 0 ; i < data.length() ; i++){
                                JSONObject row = data.getJSONObject(i);
                                int id = row.getInt("id");
                                String name = row.getString("employee_name");
                                int salary = row.getInt("employee_salary");
                                int age = row.getInt("employee_age");

                                Employer employer= new Employer(id, name, salary, age);
                                employerArrayList.add(employer);
                            }

                            // ์–ด๋Œ‘ํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ 
                            adapter = new EmployerAdapter(MainActivity.this, employerArrayList);
                            // ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ์— ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ ์šฉํ•˜๋ฉด ํ™”๋ฉด์— ๋‚˜์˜จ๋‹ค
                            recyclerView.setAdapter(adapter);

                        } catch (JSONException e) {
                            Toast.makeText(MainActivity.this,
                                    "ํŒŒ์‹ฑ ์—๋Ÿฌ",
                                    Toast.LENGTH_SHORT).show();
                            return;
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // ํ”„๋กœ๊ทธ๋ ˆ์Šค ๋ฐ”๋ฅผ ์œ ์ €์˜ ๋ˆˆ์—์„œ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•˜๋Š” ์ฝ”๋“œ
                        progressBar.setVisibility(View.GONE);

                        Toast.makeText(MainActivity.this,
                                "๋„คํŠธ์›Œํฌ ํ†ต์‹  ์—๋Ÿฌ",
                                Toast.LENGTH_SHORT).show();
                        Log.i("EMPLOYEE MAIN", error.toString());
                    }
                }
        );

        // 3. ๋„คํŠธ์›Œํฌ๋กœ ๋ณด๋‚ธ๋‹ค.
        queue.add(request);

    }
}

 

 

 


Employer.java ํด๋ž˜์Šค

package com.~.employee.model;

public class Employer {

    public int id;
    public String name;
    public int salary;
    public int age;

    public Employer(){

    }

    public Employer(int id, String name, int salary, int age) {
        this.id = id;
        this.name = name;
        this.salary = salary;
        this.age = age;
    }
}