'2018/10/05'에 해당되는 글 2건

728x90

RecyclerView 기본 개념을 자세히 다루지는 않는다.



    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
}


dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

    implementation 'gun0912.ted:tedpermission:2.0.0'
    implementation 'androidx.cardview:cardview:1.0.0'  // 레이아웃으로 사용할 CardView
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
}

최신(2020.12월) 기준으로는 implementation 'androidx.recyclerview:recyclerview:1.1.0' 를 추가하면 된다.

아래 이미지의 import는 이전 자료 기준이라고 보면 된다.


Android Studio에서 RecyclerViewAdapter 를 쉽게 만드는 방법을 유투브 동영상을 보면서 알게되어 적어둔다.

Alt + Eneter 키를 눌러서 자동완성으로 만드는 방법이다.

RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.Holder> 처럼 파란색상으로 된 클래스명은 동일하게 적어준다.

가장 먼저 Holder 클래스를 추가하고 나서 Implement methods 를 추가추고 번호 순서대로 하면 쉽게 코드가 자동 완성된다.





이렇게 하고 나면

import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;

class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.Holder> {
    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }

    public class Holder extends RecyclerView.ViewHolder {
        public Holder(View itemView) {
            super(itemView);
        }
    }
}
 


모습으로 코드가 만들어진다.

여기에 실제 추가할 코드를 반영하여 작성한다.

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;

class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.Holder> {
    Context mContext;
    private ArrayList<MessageData> mMessageData;

    public RecyclerViewAdapter(Context context, ArrayList<MessageData> arrayList) {
        mContext = context;
        mMessageData = arrayList;
    }

    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_layout,parent,false));
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position) {
        MessageData data = mMessageData.get(position);
        holder.heading.setText(data.getHeading());
        holder.message.setText(data.getMessage());
    }

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

    public class Holder extends RecyclerView.ViewHolder {
        TextView heading;
        TextView message;
        public Holder(View itemView) {
            super(itemView);
            heading = itemView.findViewById(R.id.heading);
            message = itemView.findViewById(R.id.messageBody);
        }
    }
}
 


Acitivy.java 에서 구현할 코드

RecyclerView 관련 코드만 적었다.

public class MainActivity extends AppCompatActivity {
    Context context;
    private RecyclerView mRecyclerView;
    private RecyclerViewAdapter mAdapter;
    private ArrayList<MessageData> mMessageData = new ArrayList<>();

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

        initView();
    }

    private void initView(){
        mRecyclerView = findViewById(R.id.messagelist);
        mAdapter = new RecyclerViewAdapter(this,mMessageData);
        LinearLayoutManager manager = new LinearLayoutManager(this);
        DividerItemDecoration decoration = new DividerItemDecoration(this, manager.getOrientation());

        mRecyclerView.addItemDecoration(decoration);
        mRecyclerView.setLayoutManager(manager);
        mRecyclerView.setAdapter(mAdapter);
    }
}
 



블로그 이미지

Link2Me

,
728x90

경기버스 도착정보 서비스 API 를 http://www.data.go.kr 사이트에서 받아서 XML 데이터를 JSON 으로 파싱하는 예제를 테스트하고 적어둔다.



신청하면 2년간 사용할 수 있게 되어 있다.


프로젝트 build.gradle

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}


앱 build.gradle

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.github.bumptech.glide:glide:3.8.0' // 이미지 라이브러리
    implementation 'com.android.support:recyclerview-v7:27.1.0' // ListView 개선 버전
    implementation 'com.android.support:cardview-v7:27.1.0'
    implementation 'gun0912.ted:tedpermission:2.0.0'
    implementation 'com.github.smart-fun:XmlToJson:1.1.1'
    implementation 'com.android.volley:volley:1.1.0'
}


라이브러리 최신 정보는 https://github.com/smart-fun/XmlToJson 에서 확인해서 최신버전으로 적는게 좋다.



 public class MainActivity extends AppCompatActivity {
    Context context;
    public static final String TAG = MainActivity.class.getSimpleName();
    public EditText edit;
    public Button send;
    TextView status1;
    // http://www.data.go.kr 에서 로그인 후 API 조회하여 신청 승인받은 key 값
    String key = "iLOTMTnmawGIweE3%2F4DFwv98g0F3Vv7iJA%3D%3D"; // 실제 키값이 아님 (변경처리함)

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

        initView();
    }

    private void initView() {
        status1 = (TextView)findViewById(R.id.result); //파싱된 결과확인!
        edit = (EditText) findViewById(R.id.message) ;
        send = (Button)findViewById(R.id.send);

        // message send action
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!edit.getText().toString().isEmpty()){
                    BusArriveTask(edit.getText().toString());
                    edit.setText(" ");
                }
            }
        });
    }

    private void BusArriveTask(String search){
        RequestQueue requestQueue = Volley.newRequestQueue(context);

        String StationId = null; // 정류소 ID
        try {
            StationId = URLEncoder.encode(search,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 버스 도착정보 목록 조회
        String url = "http://openapi.gbis.go.kr/ws/rest/busarrivalservice/station?serviceKey="+key+"&stationId="+StationId+"";
        Log.d(TAG, "URL:"+url);

        StringRequest request= new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        XMLtoJSONData(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });

        requestQueue.add(request);
    }

    private void XMLtoJSONData(String xml){
        // https://androidfreetutorial.wordpress.com/2016/11/28/how-to-convert-xml-to-json-for-android/
        XmlToJson xmlToJson = new XmlToJson.Builder(xml).build();
        // convert to a JSONObject
        JSONObject jsonObject = xmlToJson.toJson();
        Log.d(TAG, "jsonObject:"+jsonObject);

        // JSON 에서 배열은 [] 대괄호 사용, Objext 는 {} 중괄호 사용
        try {
            JSONObject response = jsonObject.getJSONObject("response");
            JSONObject msgHeader = response.getJSONObject("msgHeader");
            String resultCode = msgHeader.optString("resultCode");
            Log.d(TAG, "String resultCode :"+resultCode);

            if(resultCode.equals("0")){
                JSONObject msgBody = response.getJSONObject("msgBody");
                Log.d(TAG, "jsonObject msgBody :"+msgBody);

                JSONArray array = msgBody.getJSONArray("busArrivalList");
                for(int i=0; i < array.length();i++){
                    JSONObject obj = array.getJSONObject(i);
                    // optString which returns the value mapped by name if it exists
                    String plateNo1 =obj.optString("plateNo1"); // 첫번째 차량 번호
                    String locationNo1 =obj.optString("locationNo1"); // 첫번째 차량 위치 정보
                    String plateNo2 =obj.optString("plateNo2"); // 두번째 차량 번호
                    String locationNo2 =obj.optString("locationNo2"); // 두번째 차량 위치 정보
                    Log.d(TAG, "jString plateNo1 :"+plateNo1);
                    Log.d(TAG, "jString plateNo2 :"+plateNo2);
                    Log.d(TAG, "jString locationNo1 :"+locationNo1);
                    Log.d(TAG, "jString locationNo2 :"+locationNo2);
                }
            } else if(resultCode.equals("1")){
                Toast.makeText(context, "시스템 에러가 발생하였습니다", Toast.LENGTH_SHORT).show();
            } else if(resultCode.equals("4")){
                Toast.makeText(context, "결과가 존재하지 않습니다", Toast.LENGTH_SHORT).show();
            } else if(resultCode.equals("8")){
                Toast.makeText(context, "요청 제한을 초과하였습니다", Toast.LENGTH_SHORT).show();
            } else if(resultCode.equals("23")){
                Toast.makeText(context, "버스 도착 정보가 존재하지 않습니다", Toast.LENGTH_SHORT).show();
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

}


로그캣에만 찍어보도록 코드를 구현한 상태다.




XML 메시지를 JSON 으로 변환하면 아래와 같이 된다.

중괄호를 JSONObject response = jsonObject.getJSONObject("response"); 로 파싱하고

로그캣을 찍어서 메시지를 확인하면서 범위를 좁혀 나가면 된다.

[] 대괄호가 나오는 부분에서는 JSONArray array = msgBody.getJSONArray("busArrivalList"); 로 파싱하고 for 문을 돌려서 원하는 결과를 추출할 수 있다.





공공데이터 파싱하는데 사용한 샘플 코드를 첨부 (RecyclerView 를 이용하여 화면에 뿌리는 예제로 구현)

BusInfo_sample.zip



제대로 만들어 보려고 한다면

부산버스 어플 소스 https://github.com/kmshack/Busanbus-Android 공개된 것으로 공부하면 많은 도움이 될 거 같다.

관련 기사  : http://www.bloter.net/archives/151935

블로그 이미지

Link2Me

,