프로그래밍/안드로이드

안드로이드 - 9. 수강신청앱 강의목록 검색화면 개발하기

가카리 2018. 10. 14. 22:54
반응형

실행화면
1. 로그인을 합니다.


2. COURSE LIST 클릭


3. 다음과 같은 레이아웃을 구성하는 것이 이번 강의 목표



res/layout/fragment_course.xml

COUSE LIST를 눌렀을 때 보여주는 xml 파일입니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.kch.registration_v9.CourseFragment"
    android:orientation="vertical"

    >

    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/courseUniversityGroup"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"
        android:orientation="horizontal"
        android:layout_marginTop="10dp"
        >

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="undergraduate"
            android:id="@+id/university"
            />

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="graduate"
            android:id="@+id/graduate"
            />

    </RadioGroup>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="10dp"
            android:layout_gravity="center_horizontal"
            android:paddingRight="10dp">

            <Spinner
                android:layout_width="120dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginLeft="10dp"
                android:id="@+id/yearSpinner"></Spinner>

            <Spinner
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginLeft="10dp"
                android:id="@+id/termSpinner"></Spinner>

            <Spinner
                android:layout_width="140dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginLeft="10dp"
                android:id="@+id/areaSpinner"></Spinner>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="10dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:paddingRight="10dp"
            >

            <Spinner
                android:layout_width="230dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginLeft="10dp"
                android:id="@+id/majorSpinner"></Spinner>

            <Button
                android:layout_width="80dp"
                android:layout_height="40dp"
                android:textSize="15dp"
                android:textStyle="bold"
                android:textColor="#ffffff"
                android:background="@color/colorWarning"
                android:text="Course Search"
                android:layout_gravity="center"
                android:id="@+id/searchButton"
                android:layout_marginLeft="10dp"/>


        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:background="#ffffff"
            >

            <ListView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/courseListView"
                android:dividerHeight="10dp"
                android:divider="#ffffff"
                ></ListView>



        </LinearLayout>


</LinearLayout>

res/values/arrays.xml

Spinner를 클릭했을때 넣어줄 데이터를 여기에 정의 해줍니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="major">
        <item>정보통신공학</item>
        <item>기계공학</item>
        <item>화학공학과</item>
    </string-array>
    <string-array name="term">
        <item>1학기</item>
        <item>여름학기</item>
        <item>2학기</item>
        <item>계절학기</item>
    </string-array>
    <string-array name="graduateArea">
        <item>전공선택과목</item>
        <item>교양과목</item>
        <item>전공필수과목</item>
    </string-array>
    <string-array name="universityArea">
        <item>전공필수과목</item>
        <item>전공선택과목</item>
    </string-array>
    <string-array name="year">
        <item>2018년도</item>
        <item>2019년도</item>
        <item>2020년도</item>
        <item>2021년도</item>
        <item>2022년도</item>
        <item>2023년도</item>
        <item>2024년도</item>
        <item>2025년도</item>
        <item>2026년도</item>
    </string-array>
</resources>


CourseFragment.java

스피너와 라디오버튼 그룹을 만들고 값을 넣어줍니다.

package com.example.kch.registration_v9;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;


/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link CourseFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link CourseFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class CourseFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    public CourseFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment CourseFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static CourseFragment newInstance(String param1, String param2) {
        CourseFragment fragment = new CourseFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    //9강에 추가된 부분
    private ArrayAdapter yearAdapter;
    private Spinner yearSpinner;
    private ArrayAdapter termAdapter;

    private Spinner termSpinner;
    private ArrayAdapter areaAdapter;
    private Spinner areaSpinner;

    private String courseUniversity = "";
    private String courseYear = "";
    private String courseTerm = "";
    private String courseArea = "";


    //9강에 추가된 부분
    //Life Cycle 상 onCreate다음에 onActivityCreated가 실행됨
    //Activity의 모든 View가 만들어지고 난 다음이기 때문에 View를 변경하는 등의 작업을 할 수 있다.

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);


        final RadioGroup courseUniversityGroup = (RadioGroup)getView().findViewById(R.id.courseUniversityGroup);
        yearSpinner = (Spinner)getView().findViewById(R.id.yearSpinner);
        termSpinner = (Spinner)getView().findViewById(R.id.termSpinner);
        areaSpinner = (Spinner)getView().findViewById(R.id.areaSpinner);

        //라디오 버튼에 따라서 달라짐
        courseUniversityGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //라디오 버튼 그룹 선언
                RadioButton courseButton = (RadioButton)getView().findViewById(checkedId);

                //현재 라디오 버튼이 눌린 값의 text를 가져옴
                courseUniversity = courseButton.getText().toString();

                //arrays.xml의 내용을 이용해서 단순한 스피너를 만드는 부분
                yearAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.year, android.R.layout.simple_spinner_dropdown_item);
                yearSpinner.setAdapter(yearAdapter);//여기서 스피너뷰에 어댑터패턴을 이용해서 데이터를 연결해줌


                //위와 동일
                termAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.term, android.R.layout.simple_spinner_dropdown_item);
                termSpinner.setAdapter(termAdapter);

                //라디오버튼의 상태에 따라서 학부와 대학원으로 나눔
                if(courseUniversity.equals("undergraduate")){
                    areaAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.universityArea, android.R.layout.simple_spinner_dropdown_item);
                    areaSpinner.setAdapter(areaAdapter);
                }else{
                    areaAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.graduateArea, android.R.layout.simple_spinner_dropdown_item);
                    areaSpinner.setAdapter(areaAdapter);
                }

            }
        });
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_course, container, false);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    /*
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

강의에서 삭제함    */

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}



 MainActivity.java

맨 마지막부분에 메인화면에서 백버튼을 두번 누르면 앱이 종료되게 추가했습니다.


package com.example.kch.registration_v9;

import android.os.AsyncTask;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

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

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    //7강때 추가된 부분
    private ListView noticeListView;
    private NoticeListAdapter adapter;
    private List<Notice> noticedList;


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

        //7강때 추가된 부분
        noticeListView = (ListView)findViewById(R.id.noticeListView);
        noticedList = new ArrayList<Notice>();
        //8강때 삭제됨
       /* noticedList.add(new Notice("공지사항", "gakari", "2018-09-09"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-10"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-11"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-12"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-13"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-14"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-15"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-16"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-17"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-18"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-19"));
        noticedList.add(new Notice("공지사항", "gakari", "2018-09-20"));*/
        adapter = new NoticeListAdapter(getApplicationContext(), noticedList);
        noticeListView.setAdapter(adapter);


        final Button courseButton = (Button)findViewById(R.id.courseButton);
        final Button statisticsButton = (Button)findViewById(R.id.statisticsButton);
        final Button scheduleButton = (Button)findViewById(R.id.scheduleButton);
        final LinearLayout notice = (LinearLayout)findViewById(R.id.notice);

        courseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                notice.setVisibility(View.GONE);//공지사항이 안보임
                courseButton.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
                statisticsButton.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                scheduleButton.setBackgroundColor(getResources().getColor(R.color.colorPrimary));

                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.fragment, new CourseFragment());//프래그먼트를 바꿔줌
                fragmentTransaction.commit();
            }
        });

        statisticsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                notice.setVisibility(View.GONE);//공지사항이 안보임
                courseButton.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                statisticsButton.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
                scheduleButton.setBackgroundColor(getResources().getColor(R.color.colorPrimary));

                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.fragment, new StatisticsFragment());//프래그먼트를 바꿔줌
                fragmentTransaction.commit();
            }
        });

        scheduleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                notice.setVisibility(View.GONE);//공지사항이 안보임
                courseButton.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                statisticsButton.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                scheduleButton.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));

                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.fragment, new ScheduleFragment());//프래그먼트를 바꿔줌
                fragmentTransaction.commit();
            }
        });

        //8강때 추가된부분
        //AsyncTask 실행 부분
        new BackgroundTask().execute();

    }

    //PHP서버에 접속해서 JSON타입으로 데이터를 가져옴
    class BackgroundTask extends AsyncTask<Void, Void, String>{
        String target;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            target = "http://10.0.2.2:8080/registration/NoticeList.php";

        }

        //실제 데이터를 가져오는 부분임
        @Override
        protected String doInBackground(Void... voids) {
            try{

                URL url = new URL(target);
                HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String temp;//결과 값을 여기에 저장함
                StringBuilder stringBuilder = new StringBuilder();

                //버퍼생성후 한줄씩 가져옴
                while((temp = bufferedReader.readLine()) != null){
                    stringBuilder.append(temp + "\n");
                }

                bufferedReader.close();
                inputStream.close();
                httpURLConnection.disconnect();

                return stringBuilder.toString().trim();//결과값이 여기에 리턴되면 이 값이 onPostExcute의 파라미터로 넘어감

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

            return null;
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }

        //여기서는 가져온 데이터를 Notice객체에 넣은뒤 리스트뷰 출력을 위한 List객체에 넣어주는 부분
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            try{
                JSONObject jsonObject = new JSONObject(result);
                JSONArray jsonArray = jsonObject.getJSONArray("response");
                int count = 0;
                String noticeContent, noticeName, noticeDate;


                //json타입의 값을 하나씩 빼서 Notice 객체에 저장후 리스트에 추가하는 부분
                while(count < jsonArray.length()){
                    JSONObject object = jsonArray.getJSONObject(count);
                    noticeContent = object.getString("noticeContent");
                    noticeName = object.getString("noticeName");
                    noticeDate = object.getString("noticeDate");
                    Notice notice = new Notice(noticeContent, noticeName, noticeDate);
                    noticedList.add(notice);
                    count++;
                }

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

        }
    }


    //9강때 추가된부분 백버튼을 두번 누르면 앱이 종료되게 함.
    private long pressedTime;

    @Override
    public void onBackPressed() {
       // super.onBackPressed();
        //백버튼이 눌리고 1.5초안에 또 눌리면 종료가됨

        if ( pressedTime == 0 ) {
            Toast.makeText(MainActivity.this, " 한 번 더 누르면 종료됩니다." , Toast.LENGTH_LONG).show();
            pressedTime = System.currentTimeMillis();
        }
        else {
            int seconds = (int) (System.currentTimeMillis() - pressedTime);

            if ( seconds > 1500 ) {
                Toast.makeText(MainActivity.this, " 한 번 더 누르면 종료됩니다." , Toast.LENGTH_LONG).show();
                pressedTime = 0 ;
            }
            else {
                super.onBackPressed();//이걸 따라가다보면 결국 finish()를 실행 시키는 부분이 나옴
                //출처 : http://itpangpang.xyz/135
//                finish(); // app 종료 시키기
            }
        }




    }
}










반응형