간단한 뉴스 앱 만들기 #4 - 화면 전환

시작하기 앞서 api를 통해 데이터를 받아오면 검색태그인 <b></b>가 붙어서 나와 보기가 싫다.

full

그래서 입력받을 때 이 태그를 없애고 데이터를 저장하자.
NewsData class를 에서 setTitle과 setContent를 수정하자.

입력받을 때 수정된 상태로 저장하는 것이 깔끔할 것이니, 태그를 삭제하고 저장하자.
java에서 String 클래스는 replaceAll이라는 특정 문자열 제거 메소드를 제공한다.
이를 통해 <b></b>를 제거하고 저장하자.

public void setTitle(String title) {
    String fiexed_title = title.replaceAll("<b>","");
    fiexed_title = fiexed_title.replaceAll("</b>","");
    this.title = fiexed_title;
}
    public void setContent(String content) {
    String fiexed_content = content.replaceAll("<b>","");
    fiexed_content = fiexed_content.replaceAll("</b>","");
    this.content = fiexed_content;
}

그리고 나중을 위해 각 데이터의 url을 저장해두자.

String link;
public String getLink() {
    return link;
}
public void setLink(String link) {
    this.link = link;
}

ClickListener 달기

이제 우리가 만들었던 카드뷰 요소 하나하나에 각 클릭 리스터를 달아주자.
MainActivity에서 MyAdpater를 생성해주고 리사이클 뷰에 넣어주었다.
MyAdapter에서 카드뷰를 만들었으므로 MyAdapter에 데이터를 저장해주면서, 클릭리스터를 같이 저장해주자.

//Main Activiy - getNews()
 mAdapter = new MyAdapter(newsList, MainActivity.this, new View.OnClickListener() {
    @Override
    public void onClick(View v) {

    }
});
recyclerView.setAdapter(mAdapter);

이제 MyAdapter 클래스에서 받아주어야 한다.
먼저, MyAdapter에 멤버변수 View.OnClickListener onClickListener를 생성해준다.
이 클래스에서 자유롭게 사용하기 위함이다.
그리고 생성자에서 매개변수로 listener객체를 받아주고, onClickListener에 저장한다.

public static View.OnClickListener onClickListener;

public MyAdapter(List<NewsData> myDataset, Context context, View.OnClickListener OnClick) {
mDataset = myDataset;
Fresco.initialize(context);
onClickListener = OnClick;

static으로 선언한 이유는 MyViewHolder가 static class이므로 선언하였는데, 보여지는 ui에서 이 리스너가 동작하도록 해야하므로 MyViewHolder에서 다음과 같이 리스너를 설정해준다.

public static class MyViewHolder extends RecyclerView.ViewHolder {
    ...
    public LinearLayout layout;


    public MyViewHolder(LinearLayout v) {
        ...
        layout = v;

        layout.setClickable(true);
        layout.setEnabled(true);
        layout.setOnClickListener(onClickListener);
    }
}

그리고, 직접 화면을 띄우는 onBindViewHolder메소드에서 태그를 설정해주자.
해당 데이터를 상세하게 보여주는 화면에서 우리가 원하는 데이터를 불러오기 위함이다.
데이터가 리스트 셋으로 되어있으므로 구분할 태그가 필요하다.
position이라는 인덱스를 각 데이터 별로 받으므로 태그는 position으로 한다.

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    ...
    holder.layout.setTag(position);
}

또한 우리가 원하는 데이터를 받아올 수 있도록 getter를 만들어준다.

public NewsData getNewsData(int position){return mDataset.get(position);}

다시 MainActivity에서 클릭 리스너에 대하여 동작을 정의하자.

//Main Activiy - getNews()
 mAdapter = new MyAdapter(newsList, MainActivity.this, new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Object obj = v.getTag();
        if(obj != null){
            NewsData getNews = ((MyAdapter)mAdapter).getNewsData((int)v.getTag());
            try {
                Intent intent  = new Intent(MainActivity.this, NewsActivity.class);
                intent.putExtra("getNews",getNews);
                startActivity(intent);
            }catch (Exception e){
                e.getStackTrace();
            }
        }
    }
});
recyclerView.setAdapter(mAdapter);

intent를 통해 새로운 Activity화면을 열어 그 화면에 우리의 데이터를 찍을 것이다. 해당 Activity 화면을 만들어 보자.

 




NewsActivity 만들기

  1. xml파일 만들기
  2. NewsActivity 클래스 만들기

xml파일을 새로 생성하려 했으나 activity_main.xml파일을 그냥 남겨두고 있었다.
이를 사용하자.

 

그리고 CardView를 그대로 활용하자.(이쁘니까?)
row_news.xml 내용을 그대로 복붙하고 root layout에 설정해두었던 height를 match_parent로 바꾸어준다.

 

제목과 이미지를 다시 분리시키고 각자가 원하는대로 재배치 하자.
나는 제목 - 이미지 - 본문 이 순으로 재 배치 하였다.

  • activity_main.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="match_parent"
          xmlns:fresco="http://schemas.android.com/tools"
          android:orientation="vertical">
          <androidx.cardview.widget.CardView
              xmlns:card_view="http://schemas.android.com/apk/res-auto"
              android:id="@+id/card_view"
              android:layout_gravity="center"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              card_view:cardCornerRadius="4dp"
              android:layout_margin="12dp"
              >
              <LinearLayout
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical"
                  >
                  <LinearLayout
                      android:id="@+id/LinearLayout_goChrome"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:orientation="vertical">
                      <TextView
                          android:id="@+id/TextView_Title"
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content"
                          android:text="text"
                          android:textSize="30dp"
                          android:padding="8dp"
                          android:gravity="center"
                          android:textStyle="bold|normal"
                          android:maxLines="1"
                          android:ellipsize="end"
                          />
                      <LinearLayout
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content"
                          android:paddingLeft="20dp"
                          android:paddingRight="20dp"
                          >
                          <com.facebook.drawee.view.SimpleDraweeView
                              android:id="@+id/ImageView_Title"
                              android:layout_width="match_parent"
                              android:layout_height="180dp"
                              android:padding="10dp"
                              fresco:placeholderImage="@drawable/ic_launcher_foreground"
                              />
                      </LinearLayout>
                  </LinearLayout>
                  <TextView
                      android:id="@+id/TextView_Content"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:text="text"
                      android:textSize="20dp"
                      android:gravity="top|left"
                      android:paddingLeft="6dp"
                      android:paddingRight="6dp"
                      />
              </LinearLayout>
          </androidx.cardview.widget.CardView>
      </LinearLayout>

이제 NewsActivity.class를 만들고 onCreate를 오버라이딩을 해주자.
goChrome id는 나중에 url연결을 위한 이름이므로 잠시 잊어준다.

그 후 위 xml파일에서 설정해둔 이름을 다 선언해둔다.

public TextView TextView_Title;
public TextView TextView_Content;
public SimpleDraweeView ImageView_Title;

레이아웃에서 id를 통해 메모리를 받아와준다.

TextView_Title = findViewById(R.id.TextView_Title);
TextView_Content = findViewById(R.id.TextView_Content);
ImageView_Title = findViewById(R.id.ImageView_Title);

이전 화면에서 Intent를 통해 데이터를 넘겨주었으므로, 여기서 Intent를 통해 데이터를 받아준다.
바로 받아온 데이터를 NewsData 타입으로 바꾸어 준다.

Intent intent = getIntent();
NewsData getNews = (NewsData) intent.getExtras().get("getNews");

이제 MyAdapter에서 onBindViewHolder메소드를 정의했던 것처럼 텍스트, 이미지를 세팅해주자.

TextView_Title.setText(getNews.getTitle());
TextView_Content.setText(getNews.getContent());

Uri uri = Uri.parse(getNews.getUrlToImage());
ImageView_Title.setImageURI(uri);
  • NewsActivity.class 전체코드

      package com.example.newstest;
    
      import ...
    
      public class NewsActivity extends AppCompatActivity {
          public TextView TextView_Title;
          public TextView TextView_Content;
          public SimpleDraweeView ImageView_Title;
    
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
    
              TextView_Title = findViewById(R.id.TextView_Title);
              TextView_Content = findViewById(R.id.TextView_Content);
              ImageView_Title = findViewById(R.id.ImageView_Title);
    
              Intent intent = getIntent();
              NewsData getNews = (NewsData) intent.getExtras().get("getNews");
              TextView_Title.setText(getNews.getTitle());
              TextView_Content.setText(getNews.getContent());
    
              Uri uri = Uri.parse(getNews.getUrlToImage());
              ImageView_Title.setImageURI(uri);
    
          }
      }
  • 실행 화면

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기