안드로이드2018. 8. 1. 11:42

6. 각각의 게시글에 대한 레이아웃 작성하기 - listview.xml

<?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="50dp"
    android:layout_marginBottom="10dp">

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

        <TextView
            android:id="@+id/title"
            android:layout_width="250dp"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:textColor="#666"
            android:paddingLeft="20dp"
            android:text=""
            android:textSize="15dp"/>

        <TextView
            android:id="@+id/date"
            android:layout_width="90dp"
            android:layout_height="match_parent"
            android:gravity="center|right"
            android:textColor="#999"
            android:text=""
            android:textSize="13dp"/>

    </LinearLayout>

</LinearLayout>


7. Adapter 클래스 생성

public class BoardAdapter extends BaseAdapter {
  private Context context;
  private List<Board> boardList;

  public BoardAdapter(List<Board> boardList) {
    this.boardList = boardList;
  }

  @Override
  public int getCount() {
    return boardList.size();
  }

  @Override
  public Object getItem(int i) {
    return boardList.get(i);
  }

  @Override
  public long getItemId(int i) {
    return i;
  }

  @Override
  public View getView(int i, View view, ViewGroup viewGroup) {
    final int pos = i; // ListView 위치(첫 번째 = 0)
    context = viewGroup.getContext();

    if(view == null) {
      LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      if(inflater != null)
        view = inflater.inflate(R.layout.listview, viewGroup, false); 
    }

    TextView title = view.findViewById(R.id.title),
             date = view.findViewById(R.id.date);

    Board board = boardList.get(i);

    title.setText(board.getTitle());
    date.setText(board.getCreateDate());

    view.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        // 게시글 터치 시 내용 보여주는 다이얼로그 띄우기
        showContent(boardList.get(pos).getTitle(), boardList.get(pos).getContent()); 
      }
    });

    return view;
  }

  private void showContent(String title, String content) {
    final Dialog dialog = Util.getCustomDialog(context, R.layout.content_dialog); 
    // 8-9번 참고
    dialog.setCancelable(false);
    dialog.show();
    TextView dTitle = dialog.findViewById(R.id.dialog_title),
             dContent = dialog.findViewById(R.id.dialog_content);
    ImageView dClose = dialog.findViewById(R.id.dialog_close_img);
    Button bClose = dialog.findViewById(R.id.dialog_close);
    dTitle.setText(title);
    dContent.setText(content);
    dContent.setMovementMethod(new ScrollingMovementMethod());
    dClose.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        dialog.dismiss();
      }
    });
    bClose.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        dialog.dismiss();
      }
    });
  }
}


8. 내용을 보여줄 커스텀 다이얼로그 레이아웃 작성

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center"
    android:background="@drawable/custom_dialog_bg"
    android:orientation="vertical" >

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

        <TextView
            android:id="@+id/dialog_title"
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:layout_marginBottom="6dp"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="6dp"
            android:padding="7dp"
            android:text=""
            android:textColor="#666"
            android:textSize="14dp" />

        <ImageView
            android:id="@+id/dialog_close_img"
            android:layout_width="22dp"
            android:layout_height="22dp"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:contentDescription="@null"
            android:src="@drawable/btn_close" />
        
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#EEE" />

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

        <TextView
            android:id="@+id/dialog_content"
            android:layout_width="match_parent"
            android:layout_height="290dp"
            android:lineSpacingExtra="4dp"
            android:padding="10dp"
            android:scrollbars="vertical"
            android:scrollbarSize="3dp"
            android:text=""
            android:textColor="#555"
            android:textSize="14dp" />
        
    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout_dialog_close"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/dialog_close"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:layout_gravity="center"
            android:background="@drawable/btn_style_blue"
            android:text="@string/name_close"
            android:textColor="#FFF"
            android:textSize="16dp" />
        
    </LinearLayout>

</LinearLayout>


- 화면은 아래와 같다.



9. Util.getCustomDialog 작성

public class Util {
  // ...
  public static Dialog getCustomDialog(Context context, int layout) {
    Dialog dialog = new Dialog(context, R.style.FullHeightDialog);
    dialog.setContentView(layout);
    return dialog;
  }
  // ...
}


※ FullHeightDialog - styles.xml

  <!-- ... -->
  <style name="FullHeightDialog" parent="android:style/Theme.Dialog">
      <item name="android:windowNoTitle">true</item>
      <item name="android:windowBackground">@android:color/transparent</item>
  </style>
  <!-- ... -->


- 실제 화면


Posted by 홍규홍규
안드로이드2018. 8. 1. 11:17

- 안드로이드에서 해당 페이지로부터 데이터를 가져오는 작업.

3-1. build.gradle에 Volley 추가

implementation 'com.android.volley:volley:1.1.1'


3-2. 게시판 리스트를 출력할 Layout 작성 - activity_board.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"
    android:background="#FAFAFA">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:background="#FFF"
        android:textSize="20dp"
        android:textColor="#666"
        android:text="게시글 목록"/>

    <ImageView
        android:id="@+id/img_close"
        android:layout_width="28dp"
        android:layout_height="28dp"
        android:src="@drawable/btn_close"
        android:layout_marginTop="11dp"
        android:layout_marginEnd="18dp"
        android:layout_alignParentEnd="true"/>

    <View
        android:id="@+id/viewline_01"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/title"
        android:background="#EEE" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_below="@id/viewline_01">

        <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:dividerHeight="1dp"
            android:divider="#EEE"
            android:background="@drawable/custom_bg_01"/>

    </LinearLayout>

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:alpha="0.3"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:visibility="gone" />

</RelativeLayout>


※ 화면은 다음과 같다.




4. Volley 객체를 생성한다. (싱글톤 패턴 적용)

public class MyVolley {
  private static MyVolley instance;
  private RequestQueue requestQueue;

  public static MyVolley getInstance(Context context) {
    if(instance == null)
      instance = new MyVolley(context);
    return instance;
  }

  private MyVolley(Context context) {
    requestQueue = Volley.newRequestQueue(context);
  }

  public RequestQueue getRequestQueue() {
    return requestQueue;
  }
}


4.서버사이드 VO와 동일한 Board VO를 생성해준다. (동일하므로 생략)


5. Volley 객체를 이용하여 게시판 데이터를 가져온다.

public class BoardActivity extends Activity {
  private Context mContext
  private ListView mListView;
  private ProgressBar progressBar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mContext = this;
    setContentView(R.layout.activity_board);    

    mListView = findViewById(R.id.listview);
    progressBar = findViewById(R.id.progressBar);
    ImageView btnClose = findViewById(R.id.img_close);
    btnClose.setOnClickListener(new View.OnClickListener() { // X 버튼
      @Override
      public void onClick(View view) {
        finish();
      }
    });

    getBoardData(); // 게시판 데이터 가져오기
  }
  
  private void setProgressBar(int visibility) {
    progressBar.setVisibility(visibility);
  }

  private void getBoardData() {
    setProgressBar(View.VISIBLE);
    final String url = getString(R.string.url_get_board); // 서버사이드 페이지 웹 주소 
    RequestQueue queue = MyVolley.getInstance(mContext).getRequestQueue();
    JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.GET, url, new JSONObject(),
                                                          successListener(), errorListener());
    queue.add(jsonRequest);
  }
 
  private void parsingJSONData(String data) {
    List<Board> mList = new ArrayList<>();
    try {
      JSONArray jArray = new JSONArray(data);
      for(int i = 0; i < jArray.length(); i++) {
        Board board = new Board();
        JSONObject jObject = jArray.getJSONObject(i);
        board.setNno(Integer.parseInt(jObject.getString("nno")));
        board.setTitle(jObject.getString("title"));
        board.setContent(jObject.getString("content"));
        board.setCreateDate(jObject.getString("createDatet"));
        mList.add(board );
      }
      mListView.setAdapter(new BoardAdapter(mList));

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

  private Response.Listener<JSONObject> successListener() {
    return new Response.Listener<JSONObject>() {
      @Override
      public void onResponse(JSONObject response) {
        setProgressBar(View.GONE);
        String result = null;
        try {
          result = response.getString("data");
        } catch(JSONException e) {
          e.printStackTrace();
        }
        parsingJSONData(result);
      }
    };
  }

  private Response.ErrorListener errorListener() {
    return new Response.ErrorListener() {
      @Override
      public void onErrorResponse(VolleyError error) {
        // Util.showToast(mContext, getString(R.string.msg_network_error_01));
        // 에러 메시지 작성
      }
    };
  }
}


Posted by 홍규홍규
안드로이드2018. 8. 1. 10:57

※ 서버사이드 언어는 JSP로 작성


1. 게시글 각각의 데이터를 담을 VO를 작성한다. - Board.java

  게시판 구조는 게시글번호(nno), 제목(title), 내용(content), 작성일(createDate)로 구성.

public class Board {
  protected int nno;
  protected String title;
  protected String content;
  protected String createDate;
  
  public int getNno() {
    return nno;
  }
  public void setNno(int nno) {
    this.nno = nno;
  }
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  public String getContent() {
    return content;
  }
  public void setContent(String content) {
    this.content = content;
  }
  public String getCreateDate() {
    return createDate;
  }
  public void setCreateDate(String createDate) {
    this.cre_dt = createDate;
  }
}


2. 서버로부터 게시글 리스트를 가져오는 쿼리를 작성한다. - get_list.jsp

  그리고 가져온 데이터를 json 형식으로 출력하는 코드를 작성한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="org.json.simple.*" %>
<%@ page import="java.sql.*" import="java.util.*" 
    import="VO작성한패키지.Board" %>
<%
Connection con = null;
Statement stmt = null;
List list = null;
try {
  Class.forName("com.mysql.cj.jdbc.Driver");
  con = DriverManager.getConnection("jdbc:서버주소?serverTimezone=UTC", "아이디", "비밀번호");
  if(con == null)
    throw new Exception("데이터베이스에 연결할 수 없습니다.");
 
  stmt = con.createStatement();
  String query = String.format("SELECT * FROM BOARD ORDER BY createDate DESC"); 

  list = new ArrayList(); // 리스트 생성
  Board board = null;
  ResultSet rs = stmt.executeQuery(query);

  JSONObject jObject = new JSONObject(); // 객체를 담을 JSON 오브젝트 생성
  JSONArray jArray = new JSONArray(); // 객체 리스트를 담을 JSON 배열 생성

  int jCount = 0; // JSON 형식 배열 index
  while(rs.next()) {
    JSONObject innerObj = new JSONObject();
    innerObj.put("nno", rs.getInt(1)); // 게시글 번호
    innerObj.put("title", rs.getString(2)); // 게시글 제목
    innerObj.put("content", rs.getString(3)); // 게시글 내용
    innerObj.put("createDate", rs.getString(4)); // 게시글 작성일
    jArray.add(jCount, innerObj);
    jCount++;
  }
  jObject.put("data", jArray);
  out.print(jObject);

  rs.close();
} catch(Exception e) {
  e.printStackTrace();
} finally {
  try {
    stmt.close();
    con.close();
  } catch(Exception ignored) {}
}
%>
Posted by 홍규홍규