반응형












출처 - http://android-pratap.blogspot.kr/2015/12/horizontal-recyclerview-in-vertical.html?m=1



구글 플레이 스토어 앱처럼 수직방향의 RecyclerView 안에 여러 개의 수평방향 RecyclerView 를 넣은 구현입니다..  RecylerView의 한 줄마다 여러 개의 웹뷰를 넣어 보았습니다.





준비과정


app폴더 아래의  build.gradle에 아래 빨간색 두 줄을 추가. 주의할 점은 compileSdkVersion 의 버전과 일치를 시켜야 합니다.


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
apply plugin: 'com.android.application'
 
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.1"
 
    defaultConfig {
        applicationId "com.tistory.webnautes.horizontalrecyclerviewinvertical"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.1.1'
    compile 'com.android.support:recyclerview-v7:24.0.0'
    compile 'com.android.support:cardview-v7:24.0.0'
}
 
cs




1. 모델 관련 클래스 선언


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
package com.tistory.webnautes.horizontalrecyclerviewinvertical;
 
 
/*
 * RecyclerView의 하나의 아이템에 대한 모델 정의
 */
public class SingleItemModel {
 
 
    private String name;
    private String url;
    private String description;
 
 
    public SingleItemModel() {
    }
 
    public SingleItemModel(String name, String url, String description) {
        this.name = name;
        this.url = url;
        this.description = description;
    }
 
 
    public String getUrl() {
        return url;
    }
 
    public void setUrl(String url) {
        this.url = url;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
 
}
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
package com.tistory.webnautes.horizontalrecyclerviewinvertical;
 
import java.util.ArrayList;
 
/*
 * 하나의 섹션(horizontal recyclerview를 위한)에 대한 모델
 */
public class SectionDataModel {
 
    private String headerTitle;
    private ArrayList<SingleItemModel> allItemsInSection;
 
 
    public SectionDataModel() {
 
    }
    public SectionDataModel(String headerTitle, ArrayList<SingleItemModel> allItemsInSection) {
        this.headerTitle = headerTitle;
        this.allItemsInSection = allItemsInSection;
    }
 
 
 
    public String getHeaderTitle() {
        return headerTitle;
    }
 
    public void setHeaderTitle(String headerTitle) {
        this.headerTitle = headerTitle;
    }
 
    public ArrayList<SingleItemModel> getAllItemsInSection() {
        return allItemsInSection;
    }
 
    public void setAllItemsInSection(ArrayList<SingleItemModel> allItemsInSection) {
        this.allItemsInSection = allItemsInSection;
    }
 
 
}
cs




2. RecyclerView를 보여주기 위한 액티비티


MainActivity


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
package com.tistory.webnautes.horizontalrecyclerviewinvertical;
 
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
 
 
import java.util.ArrayList;
 
public class MainActivity extends AppCompatActivity {
 
    private Toolbar toolbar;
 
 
    ArrayList<SectionDataModel> allSampleData;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("RecyclerView Example");
        setSupportActionBar(toolbar);
 
 
        allSampleData = new ArrayList<SectionDataModel>();
 
 
        createDummyData();
 
 
        RecyclerView my_recycler_view = (RecyclerView) findViewById(R.id.my_recycler_view);
 
        my_recycler_view.setHasFixedSize(true);
 
        RecyclerViewDataAdapter adapter = new RecyclerViewDataAdapter(this, allSampleData);
 
        my_recycler_view.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
 
        my_recycler_view.setAdapter(adapter);
 
 
    }
 
    public void createDummyData() {
        for (int i = 1; i <= 3; i++) {
 
            SectionDataModel dm = new SectionDataModel();
 
            dm.setHeaderTitle("Section " + i);
 
            ArrayList<SingleItemModel> singleItem = new ArrayList<SingleItemModel>();
            singleItem.add(new SingleItemModel("네이버""http://m.naver.com/""네이버" ));
            singleItem.add(new SingleItemModel("다음""http://m.daum.net/""다음" ));
            singleItem.add(new SingleItemModel("구글""http://m.google.com/""구글" ));
 
            dm.setAllItemsInSection(singleItem);
 
            allSampleData.add(dm);
 
        }
    }
}
cs



activity_main.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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
 
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="8dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
 
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none" />
 
 
</LinearLayout>
cs




3. 수직방향의 RecyclerView를 위한 Adapter 클래스 생성


RecyclerViewDataAdapter


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
package com.tistory.webnautes.horizontalrecyclerviewinvertical;
 
import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
 
 
import java.util.ArrayList;
 
public class RecyclerViewDataAdapter extends RecyclerView.Adapter<RecyclerViewDataAdapter.ItemRowHolder> {
 
    private ArrayList<SectionDataModel> dataList;
    private Context mContext;
 
    public RecyclerViewDataAdapter(Context context, ArrayList<SectionDataModel> dataList) {
        this.dataList = dataList;
        this.mContext = context;
    }
 
    @Override
    public ItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, null);
        ItemRowHolder mh = new ItemRowHolder(v);
        return mh;
    }
 
    @Override
    public void onBindViewHolder(ItemRowHolder itemRowHolder, int i) {
 
        final String sectionName = dataList.get(i).getHeaderTitle();
 
        ArrayList singleSectionItems = dataList.get(i).getAllItemsInSection();
 
        itemRowHolder.itemTitle.setText(sectionName);
 
        SectionListDataAdapter itemListDataAdapter = new SectionListDataAdapter(mContext, singleSectionItems);
 
        itemRowHolder.recycler_view_list.setHasFixedSize(true);
        itemRowHolder.recycler_view_list.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
        itemRowHolder.recycler_view_list.setAdapter(itemListDataAdapter);
 
 
        itemRowHolder.btnMore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
 
 
                Toast.makeText(v.getContext(), "click event on more, "+sectionName , Toast.LENGTH_SHORT).show();
 
 
 
            }
        });
 
    }
 
    @Override
    public int getItemCount() {
        return (null != dataList ? dataList.size() : 0);
    }
 
    public class ItemRowHolder extends RecyclerView.ViewHolder {
 
        protected TextView itemTitle;
 
        protected RecyclerView recycler_view_list;
 
        protected Button btnMore;
 
 
 
        public ItemRowHolder(View view) {
            super(view);
 
            this.itemTitle = (TextView) view.findViewById(R.id.itemTitle);
            this.recycler_view_list = (RecyclerView) view.findViewById(R.id.recycler_view_list);
            this.btnMore= (Button) view.findViewById(R.id.btnMore);
 
 
        }
 
    }
 
}
cs



list_item.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
49
50
<?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="wrap_content"
              android:background="?android:selectableItemBackground"
              android:orientation="vertical"
              android:padding="5dp">
 
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="2dp">
 
 
        <TextView
            android:id="@+id/itemTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:layout_gravity="center_vertical"
            android:layout_toLeftOf="@+id/btnMore"
            android:text="Sample title"
            android:textColor="@android:color/black"
            android:textSize="18sp" />
 
        <Button
            android:id="@+id/btnMore"
            android:layout_width="wrap_content"
            android:layout_height="42dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:text="more"
            android:textColor="#FFF" />
 
 
    </RelativeLayout>
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view_list"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_gravity="center_vertical"
        android:orientation="horizontal" />
 
 
</LinearLayout>
cs



4. 수평방향의 RecyclerView를 위한 Adapter 클래스 생성


SectionListDataAdapter


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
package com.tistory.webnautes.horizontalrecyclerviewinvertical;
 
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
 
 
 
import java.util.ArrayList;
 
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {
 
    private ArrayList<SingleItemModel> itemsList;
    private Context mContext;
 
    public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList) {
        this.itemsList = itemsList;
        this.mContext = context;
    }
 
    @Override
    public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_single_card, null);
        SingleItemRowHolder mh = new SingleItemRowHolder(v);
        return mh;
    }
 
    @Override
    public void onBindViewHolder(SingleItemRowHolder holder, int i) {
 
        SingleItemModel singleItem = itemsList.get(i);
 
        holder.tvTitle.setText(singleItem.getName());
        String url =singleItem.getUrl().toString();
 
        holder.webView.setWebViewClient(new WebViewClient()); // 이걸 안해주면 새창이 뜸
        holder.webView.loadUrl(url);
 
    }
 
    @Override
    public int getItemCount() {
        return (null != itemsList ? itemsList.size() : 0);
    }
 
    public class SingleItemRowHolder extends RecyclerView.ViewHolder {
 
        protected TextView tvTitle;
        protected WebView webView;
 
 
        public SingleItemRowHolder(View view) {
            super(view);
 
            this.tvTitle = (TextView) view.findViewById(R.id.tvTitle);
            this.webView = (WebView)view.findViewById(R.id.webview);
 
 
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
 
                    Toast.makeText(v.getContext(), tvTitle.getText(), Toast.LENGTH_SHORT).show();
 
                }
            });
 
 
        }
 
    }
 
}
cs



list_single_card.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
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
                                    xmlns:card_view="http://schemas.android.com/apk/res-auto"
                                    android:layout_width="match_parent"
                                    android:layout_height="wrap_content"
                                    android:orientation="horizontal"
                                    card_view:cardCornerRadius="5dp"
                                    card_view:cardUseCompatPadding="true"
    >
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:padding="0dp"
        android:background="?android:selectableItemBackground"
        android:orientation="vertical">
 
        <WebView
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:id="@+id/webview"/>
 
 
        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/webview"
            android:gravity="center"
            android:padding="5dp"
            android:text="Sample title"
            android:textColor="@android:color/black"
            android:textSize="18sp" />
 
 
    </LinearLayout>
 
</android.support.v7.widget.CardView>
cs




5. styles.xml을 다음 내용으로 대체


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<resources>
 
    <style name="AppTheme" parent="BaseTheme">
    </style>
 
    <!-- Base application theme. -->
    <style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
 
    </style>
 
</resources>
 
cs




AndroidManifest.xml에 아래 빨간색 부분을 추가


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.tistory.webnautes.horizontalrecyclerviewinvertical">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:hardwareAccelerated="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
 
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
 
</manifest>
cs




반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts