티스토리 뷰

#페이스북 뉴스피드 보여주기


페이스북을 메시지와 스토리, 링크를 구분해서 오른쪽 그림처럼 만들어 보려고 한다.




  • 전체 프로젝트 구조






1. 각각의 레이아웃을 만든다.


  • list_item_link.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

   android:orientation="vertical"

   android:layout_width="match_parent"

   android:layout_height="match_parent">

   <TextView

       android:text="Link"

       android:textColor="#F3F3F3"

       android:background="#333333"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:padding="2dp"/>

   <TextView

       android:id="@+id/tvSubject"

       android:background="#22000000"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:text="Subject"

       android:textSize="20dp"

       android:textColor="#000000"

       android:paddingLeft="5dp"

       android:paddingTop="5dp"

       android:paddingBottom="3dp"/>

</LinearLayout>

Colored by Color Scripter

cs



  • List_item_message.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

   android:orientation="vertical"

   android:layout_width="match_parent"

   android:layout_height="match_parent">

   <TextView

       android:text="Message"

       android:textColor="#F3F3F3"

       android:background="#333333"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:padding="2dp"/>

   <TextView

       android:id="@+id/tvSubject"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:text="Subject"

       android:textSize="20dp"

       android:textColor="#000000"

       android:paddingLeft="5dp"

       android:paddingTop="5dp"

       android:paddingBottom="3dp"/>

   <LinearLayout

       android:layout_width="match_parent"

       android:layout_height="wrap_content">

       <TextView

           android:id="@+id/tvAuthor"

           android:layout_weight="9"

           android:layout_width="wrap_content"

           android:layout_height="match_parent"

           android:text="글쓴이"

           android:paddingLeft="5dp" />

       <TextView

           android:id="@+id/tvHitCount"

           android:layout_weight="1"

           android:layout_width="wrap_content"

           android:layout_height="match_parent"

           android:text="999"

           android:gravity="right"

           android:paddingRight="5dp"/>

   </LinearLayout>

</LinearLayout>

Colored by Color Scripter

cs




  • list_item_story.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

   android:orientation="vertical"

   android:layout_width="match_parent"

   android:layout_height="match_parent">

   <TextView

       android:text="Story"

       android:textColor="#F3F3F3"

       android:background="#333333"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:padding="2dp"/>

   <TextView

       android:id="@+id/tvSubject"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:text="Subject"

       android:textSize="20dp"

       android:textColor="#000000"

       android:paddingLeft="5dp"

       android:paddingTop="5dp"

       android:paddingBottom="3dp"/>

</LinearLayout>

Colored by Color Scripter

cs


3. MainActivity.java에 아래 세가지 메서드를 추가해준다.

      /**

       * 아이템의 속성에 따라서 보여질 Item Layout을 정해준다.

       * @param position

       * @return

       */

      @Override

      public int getItemViewType(int position) {

//            return super.getItemViewType(position);

          /**

           * 만약 Message가 Null이 아니라면 list_item_message를 보여주고

           * 만약 Story가 Null이 아니라면 list_item_story를 보여주고

           * 만약 Link가 Null이 아니라면 lIst_item_link를 보여준다.

           */

          articleVO = (Post) getItem(position);

          if ( articleVO.getMessage() != null && articleVO.getMessage().length() > 0 ) {

              return 0;

          }

          else if (articleVO.getStory() != null && articleVO.getStory().length() > 0 ) {

              return 1;

          }

          else if (articleVO.getLink() != null && articleVO.getLink().length() > 0 ) {

              return 2;

          }

          return 0;

      }

      /**

       * 인덱스에 따라서 다른 레이아웃 보여주기

       * @param index

       * @return

       */

      public int getLayoutType(int index){

          if( index == 0 ) {

              return R.layout.list_item_message;

          }

          else if( index == 1 ){

              return R.layout.list_item_story;

          }

          else if( index == 2 ){

              return R.layout.list_item_link;

          }

          return -1;

      }

      /**

       * Item Layout의 개수를 정한다.

       * @return

       */

      @Override

      public int getViewTypeCount() {

          return 3;

      }

Colored by Color Scripter

cs




전체코드는 다음과 같다.


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

package com.ktds.oph.customlistview;

import android.content.Context;

import android.content.Intent;

import android.net.Uri;

import android.os.Bundle;

import android.os.Handler;

import android.support.v7.app.ActionBarActivity;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ListView;

import android.widget.TextView;

import com.ktds.oph.customlistview.facebook.Facebook;

import com.restfb.types.Post;

import java.util.List;

public class MainActivity extends ActionBarActivity {

   private ListView lvArticleList;

   private Facebook facebook;

   private Handler handler;

   @Override

   protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_main);

       handler = new Handler();

       facebook = new Facebook(this);

       facebook.auth();

       lvArticleList = (ListView) findViewById(R.id.lvArticleList);

/*        final List<ArticleVO> articleList = new ArrayList<ArticleVO>();

       for (int i = 0; i < 300; i++) {

           articleList.add(new ArticleVO("제목입니다..." + i, "글쓴이 입니다." + i, new Random().nextInt(9999) +""));

       }*/

//        lvArticleList.setAdapter(new ArticleListViewAdapter(this, articleList));

//

//        lvArticleList.setOnItemClickListener(new AdapterView.OnItemClickListener() {

//            @Override

//            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

//                Toast.makeText(MainActivity.this, id + "", Toast.LENGTH_SHORT).show();

//                ArticleVO article = articleList.get(position);

//                Toast.makeText(MainActivity.this, article.getSubject(), Toast.LENGTH_SHORT).show();

//

//                Intent intent = new Intent(getApplicationContext(), DetailActivity.class);

//                intent.putExtra("article", article);

//                startActivity(intent);

//            }

//        });

   }

   /**

    * Action Bar에 메뉴를 생성한다.

    * @param menu

    * @return

    */

   @Override

   public boolean onCreateOptionsMenu(Menu menu) {

       getMenuInflater().inflate(R.menu.list_menu, menu);

       return true;

   }

   /**

    * 메뉴 아이템을 클릭했을 때 발생되는 이벤트...

    * @param item

    * @return

    */

   @Override

   public boolean onOptionsItemSelected(MenuItem item) {

       int id = item.getItemId();

       if( id == R.id.newPost ){

           Intent intent = new Intent(this, WritePostActivity.class);

           startActivity(intent);

           //Toast.makeText(MainActivity.this, "새 글 등록 버튼을 클릭했습니다.", Toast.LENGTH_SHORT).show();

           return true;

       }

       return super.onOptionsItemSelected(item);

   }

   public void setTimeline() {

       if ( facebook.isLogin() ) {

           // ,,,, timeLine 가져오기

           facebook.getTimeline(new Facebook.TimelineSerializable() {

               @Override

               public void serialize( final List<Post> posts) {

                   handler.post(new Runnable() {

                       @Override

                       public void run() {

                           lvArticleList.setAdapter(new ArticleListViewAdapter(MainActivity.this, posts));

                       }

                   });

               }

           });

       }

   }

   private class ArticleListViewAdapter extends BaseAdapter {

       /**

        * ListView 에 Item을 셋팅할 요청자의 객체가 들어감.

        */

       private Context context;

       /**

        * ListView에 셋팅할 Item 정보들...

        */

//        private List<ArticleVO> articleList;

       private List<Post> articleList;

       private Post articleVO;

       public ArticleListViewAdapter(Context context, List<Post> articleList) {

           this.context = context;

           this.articleList = articleList;

       }

       /**

        * 아이템의 속성에 따라서 보여질 Item Layout을 정해준다.

        * @param position

        * @return

        */

       @Override

       public int getItemViewType(int position) {

//            return super.getItemViewType(position);

           /**

            * 만약 Message가 Null이 아니라면 list_item_message를 보여주고

            * 만약 Story가 Null이 아니라면 list_item_story를 보여주고

            * 만약 Link가 Null이 아니라면 lIst_item_link를 보여준다.

            */

           articleVO = (Post) getItem(position);

           if ( articleVO.getMessage() != null && articleVO.getMessage().length() > 0 ) {

               return 0;

           }

           else if (articleVO.getStory() != null && articleVO.getStory().length() > 0 ) {

               return 1;

           }

           else if (articleVO.getLink() != null && articleVO.getLink().length() > 0 ) {

               return 2;

           }

           return 0;

       }

       /**

        * 인덱스에 따라서 다른 레이아웃 보여주기

        * @param index

        * @return

        */

       public int getLayoutType(int index){

           if( index == 0 ) {

               return R.layout.list_item_message;

           }

           else if( index == 1 ){

               return R.layout.list_item_story;

           }

           else if( index == 2 ){

               return R.layout.list_item_link;

           }

           return -1;

       }

       /**

        * Item Layout의 개수를 정한다.

        * @return

        */

       @Override

       public int getViewTypeCount() {

           return 3;

       }

       /**

        * ListView에 셋팅할 Item들의 개수

        * @return

        */

       @Override

       public int getCount() {

           return this.articleList.size();

       }

       /**

        * position 번째 Item 정보를 가져옴

        * @param position

        * @return

        */

       @Override

       public Object getItem(int position) {

           return this.articleList.get(position);

       }

       /**

        * Item Index를 가져옴

        * Item Index = position

        * @param position

        * @return

        */

       @Override

       public long getItemId(int position) {

           return position;

       }

       /**

        * ListView에 Item들을 셋팅함

        * @param position : 현재 보여질 Item의 Index, 0부터 getCount() 까지 증가함

        * @param convertView :  ListView의 Item Cell 객체를 가져옴.

        * @param parent : ListView

        * @return

        */

       @Override

       public View getView(int position, View convertView, ViewGroup parent) {

           // 가장 간단한 방법 -> 메모리를 많이 먹는다.

//            if ( convertView == null ) { // 사용자가 처음으로 Flicking을 할 때, 아래쪽에 만들어지는 Cell은 null이다.

//                //Item Cell에 Layout을 적용시킬 Inflater 객체

//                LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);

//

//                // Item Cell에 Layout을 적용시킨다. true 덮어쓰기 보통 false

//                convertView = inflater.inflate(R.layout.list_item_message, parent, false);

//            }

//

//            TextView tvSubject = (TextView) convertView.findViewById(R.id.tvSubject);

//            TextView tvAuthor = (TextView) convertView.findViewById(R.id.tvAuthor);

//            TextView tvHitCount = (TextView) convertView.findViewById(R.id.tvHitCount);

//

//            ArticleVO article = (ArticleVO) getItem(position);

//

//            tvSubject.setText(article.getSubject());

//            tvAuthor.setText(article.getAuthor());

//            tvHitCount.setText(article.getHitCount());

           ItemHolder holder = null;

           int layoutType = getItemViewType(position);

           // 가장 효율적인 방법

           if ( convertView == null ) { // 사용자가 처음으로 Flicking을 할 때, 아래쪽에 만들어지는 Cell은 null이다.

           //Item Cell에 Layout을 적용시킬 Inflater 객체

           LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);

           // Item Cell에 Layout을 적용시킨다. true 덮어쓰기 보통 false

           convertView = inflater.inflate(getLayoutType(layoutType), parent, false);

           holder = new ItemHolder();

           if ( layoutType == 0 ) {

               holder.tvSubject = (TextView) convertView.findViewById(R.id.tvSubject);

               holder.tvAuthor = (TextView) convertView.findViewById(R.id.tvAuthor);

               holder.tvHitCount = (TextView) convertView.findViewById(R.id.tvHitCount);

           }

           else if ( layoutType == 1 ) {

               holder.tvSubject = (TextView) convertView.findViewById(R.id.tvSubject);

           }

           else if( layoutType == 2 ) {

               holder.tvSubject = (TextView) convertView.findViewById(R.id.tvSubject);

           }

           // convertView가 항상 holder를 업어간다.

           convertView.setTag(holder);

           }

           else {

               // null이 아니라면 끄집어 낸다.

               Log.d("RESULT", "NOT NULL");

               holder = (ItemHolder) convertView.getTag();

           }

           articleVO = (Post) getItem(position);

           if ( layoutType == 0) {

               holder.tvSubject.setText(articleVO.getMessage());

               holder.tvAuthor.setText(articleVO.getFrom().getName());

               if ( articleVO.getLikes() == null ) {

                   holder.tvHitCount.setText("0");

               }

               else

                   holder.tvHitCount.setText(articleVO.getLikes().getData().size() + "");

           }

           else if ( layoutType == 1 ) {

               holder.tvSubject.setText(articleVO.getStory());

           }

           else if ( layoutType == 2 ) {

               holder.tvSubject.setText(articleVO.getLink());

               //링크 연결

               holder.tvSubject.setOnClickListener(new View.OnClickListener() {

                   @Override

                   public void onClick(View view) {

                       Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(articleVO.getLink()));

                       startActivity(intent);

                   }

               });

           }

           return convertView;

       }

   }

   private class ItemHolder {

       public TextView tvSubject;

       public TextView tvAuthor;

       public TextView tvHitCount;

   }

}

Colored by Color Scripter

cs


4. 실행하면 다음과 같다.




필요한 다른 코드도 첨부한다.


  • ArticleVO.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

package com.ktds.oph.customlistview;

import java.io.Serializable;

public class ArticleVO implements Serializable { // intent로 보낼 수 있다.

   private String subject;

   private String author;

   private String hitCount;

   public ArticleVO(String subject, String author, String hitCount) {

       this.subject = subject;

       this.author = author;

       this.hitCount = hitCount;

   }

   public String getSubject() {

       return subject;

   }

   public void setSubject(String subject) {

       this.subject = subject;

   }

   public String getAuthor() {

       return author;

   }

   public void setAuthor(String author) {

       this.author = author;

   }

   public String getHitCount() {

       return hitCount;

   }

   public void setHitCount(String hitCount) {

       this.hitCount = hitCount;

   }

}

Colored by Color Scripter

cs


  • DetailActivity.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

package com.ktds.oph.customlistview;

import android.content.Intent;

import android.os.Bundle;

import android.support.v7.app.ActionBarActivity;

import android.widget.TextView;

public class DetailActivity extends ActionBarActivity {

   private TextView tvSubject;

   private TextView tvAuthor;

   private TextView tvHitCount;

   @Override

   protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_detail);

       tvSubject = (TextView) findViewById(R.id.tvSubject);

       tvAuthor = (TextView) findViewById(R.id.tvAuthor);

       tvHitCount = (TextView) findViewById(R.id.tvHitCount);

       Intent intent = getIntent();

       ArticleVO articleVO = (ArticleVO) intent.getSerializableExtra("article"); // serializable로 객체를 보냈을때 받을 때

       setTitle(articleVO.getSubject());

       tvSubject.setText(articleVO.getSubject());

       tvAuthor.setText(articleVO.getAuthor());

       tvHitCount.setText(articleVO.getHitCount());

   }

}

Colored by Color Scripter

cs


  • Facebook.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

package com.ktds.oph.customlistview.facebook;

import android.content.Context;

import android.util.Log;

import com.ktds.oph.customlistview.MainActivity;

import com.restfb.Connection;

import com.restfb.DefaultFacebookClient;

import com.restfb.FacebookClient;

import com.restfb.Parameter;

import com.restfb.Version;

import com.restfb.types.Post;

import com.restfb.types.User;

import java.util.ArrayList;

import java.util.List;

/**

* Created by 206-024 on 2016-06-14.

*/

public class Facebook {

   /**

    * 인증과 관련된 상수들....

    */

   private static final String APP_ID = "자신의 페이스북 앱 아이디";

   private static final String APP_SECRET = "앱 시크릿 번호";

   private static final String ACCESS_TOKEN = "액세스 토큰 번호";

   private Context context;

   /**

    * Facebook 인증 객체

    */

   private FacebookClient myFacebook;

   private boolean isLogin;

   public Facebook(Context context) {

       this.context = context;

   }

   /**

    * Facebook으로 로그인 한다.

    * @return : 로그인 성공시 true

    */

   public void auth() {

       new Thread(new Runnable() {

           @Override

           public void run() {

               // Facebook Login

               myFacebook = new DefaultFacebookClient(ACCESS_TOKEN, Version.LATEST);

               // 로그인이 성공했는지 체크한다.

               // 로그인된 계정의 정보를 가져온다.

               User me = myFacebook.fetchObject("me", User.class);

               Log.d("FACEBOOK", me.getName() + " 계정으로 로그인 함");

               isLogin = me != null;

               if ( isLogin() ) {

                   ( (MainActivity) context ).setTimeline();

               }

           }

       }).start();

   }

   public boolean isLogin() {

       return isLogin;

   }

   public void getTimeline( final TimelineSerializable timelineSerializable ) {

       new Thread(new Runnable() {

           @Override

           public void run() {

               // 나의 타임라인에서 포스트들을 가져온다.

               Connection<Post> feeds = myFacebook.fetchConnection("me/feed", Post.class, Parameter.with("fields", "from,likes,message,story,link"));

               List<Post> postList = new ArrayList<Post>();

               // 타임라인 정보들...

               for (List<Post> posts : feeds) {

                   postList.addAll(posts);

                   // 타임라인에 등록되어 있는 포스트 1건

//                    for ( Post post : posts) {

//

//

//                        if ( post.getMessage() != null ) {

//                          Log.d("FACEBOOK", post.getMessage());

//                        }

//                        if ( post.getStory() != null ) {

//                            Log.d("FACEBOOK", post.getStory());

//                        }

//                        if ( post.getCreatedTime() != null ) {

//                            Log.d("FACEBOOK", post.getCreatedTime() + "");

//                        }

//                        if ( post.getName() != null ) {

//                            Log.d("FACEBOOK", post.getName());

//                        }

//                        if ( post.getLikesCount() != null ) {

//                            Log.d("FACEBOOK", post.getLikesCount() + "");

//                        }

//

//                    }

               }

               timelineSerializable.serialize(postList);

           }

       }).start();

   }

   public interface TimelineSerializable {

       public void serialize(List<Post> posts);

   }

}

Colored by Color Scripter

cs


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함