레트로핏 사용.(java)


안드로이드 프로젝트 생성.


gradle dependencies setting.


app gradle.


dependencies {


    // 인터넷 연결 http 프로토콜

    // https://square.github.io/retrofit/

    // okhttp 를 포함하고 있다.

    implementation 'com.squareup.retrofit2:retrofit:2.5.0'


    // https://github.com/square/retrofit/tree/master/retrofit-converters/gson

    // gson 라이브러리를 포함하고 있다.

    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'


    // http 통신시 로그 보기위한 것.

    // https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor

    // okhttp 를 포함하고 있다.

    implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'



}

레트로핏을 사용할 기본 조건은 되었고.

레트로핏으로 통신을 할수있는 인터페이스 연결할 클래스 생성.

레트로핏은 http api를 인터페이스 형태로 사용한다.



public class GithubUser {



    private String login;

    private String url;

    private String name;

    private String location;

    private String repos_url;


    public String getLogin() {

        return login;

    }


    public void setLogin(String login) {

        this.login = login;

    }


    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 getLocation() {

        return location;

    }


    public void setLocation(String location) {

        this.location = location;

    }


    public String getRepos_url() {

        return repos_url;

    }


    public void setRepos_url(String repos_url) {

        this.repos_url = repos_url;

    }


    @Override

    public String toString() {

        return "login :" + login + ", url :" + url + ", name :" + name + ", location : " + location + ", repos_url :" + repos_url;

    }

}




public class GithubUserRepository {


    private String name;

    private String html_url;

    private String language;


    public String getName() {

        return name;

    }


    public void setName(String name) {

        this.name = name;

    }


    public String getHtml_url() {

        return html_url;

    }


    public void setHtml_url(String html_url) {

        this.html_url = html_url;

    }


    public String getLanguage() {

        return language;

    }


    public void setLanguage(String language) {

        this.language = language;

    }



    @Override

    public String toString() {

        return "name : " + name + ", html_url : " + html_url + ", language : " + language;

    }

}





public interface GithubService {


    @GET("users/{user}")

    Call<GithubUser> getGithubUser(@Path("user") String userName);


    @GET("users/{user}/repos")

    Call<List<GithubUserRepository>> getGithubUserRepository(@Path("user") String userName);

}




ApiConnection 클래스 생성.

실제 통신을 담당할 retrofit 객체를 생성한다.


public class ApiConnection {


    private Retrofit retrofit;


    private final String baseUrl = "https://api.github.com";


    /**

     * 생성자.

     */

    private ApiConnection() {


        OkHttpClient httpClient = new OkHttpClient.Builder()

                .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))

                .build();


        this.retrofit = new Retrofit.Builder()

                .baseUrl(baseUrl)

                // 내려받는 데이터를 gson 형식으로 데이터 변환

                .addConverterFactory(GsonConverterFactory.create())

                .client(httpClient)

                .build();

    }

        /**

     * 2. 싱글턴 패턴 구현.

     */

    private static final ApiConnection INSTANCE = new ApiConnection();


    public static ApiConnection getInstance() {

        return INSTANCE;

    }


    /**

     * interface  리턴.

     */

    public GithubService getRetrofitService() {

        return retrofit.create(GithubService.class);

    }

}





    MainActivity 에서


    void connection_01() {


        Call<GithubUser> result = ApiConnection.getInstance().getRetrofitService().getGithubUser("bearkinf");


        result.enqueue(new Callback<GithubUser>() {

            @Override

            public void onResponse(Call<GithubUser> call, Response<GithubUser> response) {


                Log.w("LOG","GithubUser : " + response.body());

            }


            @Override

            public void onFailure(Call<GithubUser> call, Throwable t) {


            }

        });

    }



oncreate()에서 함수를 호출하면 깃허브에서 내용을 가져온다.






레트로핏을 이용한 통신 프로젝트에 RxJava 넣기..



라이브러리 추가.



dependencies {

    implementation fileTree(include: ['*.jar'], dir: 'libs')

    implementation 'com.android.support:appcompat-v7:28.0.0'

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'

    implementation 'com.android.support:support-v4:28.0.0'

    testImplementation 'junit:junit:4.12'

    androidTestImplementation 'com.android.support.test:runner:1.0.2'

    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'


    //로그켓 .

    implementation 'com.github.bearkinf:AndroidLogPrintUtil_Java:1.1.1'


    // 인터페이스를 통해 인터넷 연결을 가지고 있다.

    // https://square.github.io/retrofit/

    implementation 'com.squareup.retrofit2:retrofit:2.5.0'

    // https://github.com/square/retrofit/tree/master/retrofit-converters/gson

    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

    // http 통신시 로그 보기위한 것.

    // https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor

    implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'


    // Rxjava 타입을 지원한다.

    // https://github.com/square/retrofit/tree/master/retrofit-adapters/rxjava2

    // 자체적으로 RxJava 라이브러리를 가지고 있다.(최신 버전은 아님.)

    // adapter-rxjava2 내부적으로 rxjava를 참조하나, 버그가 수정된 최신버전의 rxjava를 명확히 정의하여 해당 library를 사용하게 하도록한다.

    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'


    // https://github.com/ReactiveX/RxJava

    // 각각의 라이브러리가 RxJava를 참조하나 최신 라이브러리를 지정한다.

    // rxandroid 내부적으로 rxjava를 참조하나, 버그가 수정된 최신버전의 rxjava를 명확히 정의하여 해당 library를 사용하게 하도록한다.

    implementation "io.reactivex.rxjava2:rxjava:2.2.6"

    // https://github.com/ReactiveX/RxAndroid 스케줄러 관리 (쓰레드 관리

    // 자체적으로 RxJava 라이브러리를 가지고 있다.(최신 버전은 아님.)

    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'


}




레트로핏 인터페이스에 RxJava 추가.

public interface GithubService {


    @GET("users/{user}")

    Call<GithubUser> getGithubUser(@Path("user") String userName);



    @GET("users/{user}/repos")

    Call<List<GithubUserRepository>> getGithubUserRepository(@Path("user") String userName);



    //RxJava 용 .Observable

    @GET("users/{user}")

    Observable<GithubUser> getGithubUser2(@Path("user") String userName);



    @GET("users/{user}/repos")

    Flowable<List<GithubUserRepository>> getGithubUserRepository2(@Path("user") String userName);


}



레트로핏 객체에 RxJava 를 사용하기 위해 아답터 추가.


public class ApiConnection {


    private Retrofit retrofit;


    private final String baseUrl = "https://api.github.com";


    /**

     * 생성자.

     */

    private ApiConnection() {


        OkHttpClient httpClient = new OkHttpClient.Builder()

                .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))

                .build();


        this.retrofit = new Retrofit.Builder()

                .baseUrl(baseUrl)

                // 내려받는 데이터를 gson 형식으로 데이터 변환

                .addConverterFactory(GsonConverterFactory.create())

                // RxJava 를 사용하게되면 해당 아답터팩토리를 등록해야 한다.

                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())


                .client(httpClient)

                .build();

    }

        /**

     * 2. 싱글턴 패턴 구현.

     */

    private static final ApiConnection INSTANCE = new ApiConnection();


    public static ApiConnection getInstance() {

        return INSTANCE;

    }


    /**

     * interface  리턴.

     */

    public GithubService getRetrofitService() {

        return retrofit.create(GithubService.class);

    }

}


MainActivity에서 RxJava를 이용한 레트로핏 통신 코드 넣기.



    void connection_03() {


        /**

         * 람다식으로 사용을하려면 .

         *   compileOptions {

         *         sourceCompatibility JavaVersion.VERSION_1_8

         *         targetCompatibility JavaVersion.VERSION_1_8

         *   }

         *   넣어 주어야 한다.

         */

        LogPrintUtil.w("connection_03 start");

        ApiConnection.getInstance().getRetrofitService()

                .getGithubUser2("bearkinf")

                .subscribeOn(Schedulers.io())

                .observeOn(AndroidSchedulers.mainThread())

                .subscribe(githubUser -> {

                            LogPrintUtil.w("Observable    Data :" + githubUser);

                        }, throwable -> {


                        }

                );

    }


oncreate()에서 함수를 호출하면 깃허브에서 내용을 가져온다.




코틀린 버전은 코틀린 탭에서. 다시 작성.





코틀린 프로잭트 생성.


레트로핏 인터페이스 생성.

interface GithubService {



    @GET("users/{user}")

    fun getGithubUser(@Path("user") userName: String): Call<GithubUser>



    @GET("users/{user}/repos")

    fun getgithubUserRepository(@Path("user") userName: String): Observable<List<GithubUserRepository>>


}


레트로핏 객체 클래스 생성.

/**스테틱 클래스 생성.*/

object ApiConnection {


    private val BASE_URL = "https://api.gitHub.com"


    private val retrofit by lazy {

        val httpClient = OkHttpClient.Builder()

            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))

            .build()


        Retrofit.Builder()

            .baseUrl(BASE_URL)

            .addConverterFactory(GsonConverterFactory.create())

            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())

            .client(httpClient)

            .build()

    }

    val getRetrofitService = retrofit.create(GithubService::class.java)

}


MainActivity 에서 oncreate 에 함수 적용.

    private fun retrofitConnection_01() {


        val getGithubUser = ApiConnection.getRetrofitService.getGithubUser("bearkinf")


        getGithubUser.enqueue(object : Callback<GithubUser> {


            override fun onFailure(call: Call<GithubUser>, t: Throwable) {

            }


            override fun onResponse(call: Call<GithubUser>, response: Response<GithubUser>) {


                LogPrintUtil.w("response : ${response.body()}")


            }

        })

    }


    private fun retrofitConnection_02() {



        ApiConnection.getRetrofitService

            .getgithubUserRepository("bearkinf")

            .subscribeOn(Schedulers.io())

            .observeOn(AndroidSchedulers.mainThread())


            .subscribe({


                LogPrintUtil.w("RxJava : $it")


            }, {


            })



    }





'Java > study' 카테고리의 다른 글

자바 제네릭  (0) 2018.09.18
자바 분기문(break, continue)  (0) 2018.08.14
자바 반복문  (0) 2018.08.09
자바 제어문  (0) 2018.08.03
자바 자료형 종류  (0) 2018.07.26


안드로이드 코틀린 프로젝트.


안드로이드 targetSdkVersion 26(Oreo[8.0]) 이상으로 설정해야한다.(정책)


//코틀린 추가 확장(안드로이드 리사이클러뷰 뷰홀더에 사용함 LayoutContainer 구현.)

androidExtensions {

    experimental = true

}




안드로이드 프로젝트에서 자주 사용하는 라이브러리 정리



안드로이드 라이브러리.

Project Structure 에서 Dependencies 선택 후 Library Dependency 클릭하여 라이브러리 추가.(타겟버전에 맞추어 추가함.)



통신관련 라이브러리.


* 레트로핏 : 안드로이드 통신 라이브러리.

// 인터페이스를 통해 인터넷 연결을 가지고 있다.

// https://square.github.io/retrofit/

implementation 'com.squareup.retrofit2:retrofit:2.5.0'

   

/*레트로핏 지원 라이브러리*/    

// jsonData 형식을 클래스 객체형식으로 변환하여 준다.

// https://github.com/square/retrofit/tree/master/retrofit-converters/gson

implementation 'com.squareup.retrofit2:converter-gson:latest.version'


// Rxjava 타입을 지원한다.

// https://github.com/square/retrofit/tree/master/retrofit-adapters/rxjava2

implementation 'com.squareup.retrofit2:adapter-rxjava2:latest.version'

   

* okhttp : 안드로이드 통신 라이브러리.(레트포핏을 사용하면 okhttp 최신 버전이 들어있다)

// http,http2 통신라이브러리

// https://square.github.io/okhttp/ 

implementation 'com.squareup.okhttp3:okhttp:3.12.1'

// http 통신시 로그 보기위한 것.

// https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor 

implementation 'com.squareup.okhttp3:logging-interceptor:(insert latest version)'



* Gson : 안드로이드 json 파싱 라이브러리.

// 객체 형태로 데이터를 만들어 준다.

implementation 'com.google.code.gson:gson:2.8.5'




프로그래밍 라이브러리.

// binding :제본   bind : 묶다 


RxJava

– Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

* RxJava : 반응형 프로그래밍 라이브러리

   // https://github.com/ReactiveX/RxJava

   implementation "io.reactivex.rxjava2:rxjava:2.x.y"


/*

* RxKotlin 과 RxAndroid 는 내부적으로 RxJava를 참조하나 최신 버전의 RxJava를 명확하게 정의하여 해당 라이브러리를 쓰도록 한다.

*/


RxKotlin

RxJava bindings for Kotlin(기본적으로 RxJava 를 가지고 있다.)

* RxKotlin :    안드로이드 코틀린에서 확장지원 라이브러리.(RxJava가 있어야 하며 버전에 맞게 설정해야한다.)

        // 안드로이드 프로젝트라면. RxAndroid 설정후 .

        // https://github.com/ReactiveX/RxKotlin

        implementation 'io.reactivex.rxjava2:rxkotlin:x.y.z'


RxAndroid

RxJava bindings for Android(기본적으로 RxJava 를 가지고 있다.)

* RxAndroid :  안드로이드 프로젝트에서 사용하기 위한 라이브러리.(RxJava가 있어야 한다.) 쓰레드 관련한 모듈을 제공한다.

       // https://github.com/ReactiveX/RxAndroid

       implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

       // Because RxAndroid releases are few and far between, it is recommended you also

       // explicitly depend on RxJava's latest version for bug fixes and new features.

       // (see https://github.com/ReactiveX/RxJava/releases for latest 2.x.x version)

       implementation 'io.reactivex.rxjava2:rxjava:2.x.x'

       

* RxBinding 를 사용하기 위한 추가 지원 라이브러리들.

//RxBinding : RxJava binding APIs for Android UI widgets from the platform and support libraries.

implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2'

//

implementation 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.1.0'

implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4-kotlin:2.1.0'

implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7-kotlin:2.1.0'

implementation 'com.jakewharton.rxbinding2:rxbinding-design-kotlin:2.1.0'

implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7-kotlin:2.1.0'

*RxPermission : 안드로이드 권한 라이브러리

//https://github.com/tbruyelle/RxPermissions

implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'


* RxLifecycle : RxJava를 사용하면서 subscribe를 해제 하지 않으면 메모리릭이 발생될수도있기에 서브스크라이브 종료를 해주는 라이브러리.

// https://github.com/trello/RxLifecycle

implementation 'com.trello.rxlifecycle3:rxlifecycle:3.0.0'


// If you want to bind to Android-specific lifecycles

implementation 'com.trello.rxlifecycle3:rxlifecycle-android:3.0.0'


// If you want pre-written Activities and Fragments you can subclass as providers

implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.0.0'


// If you want pre-written support preference Fragments you can subclass as providers

implementation 'com.trello.rxlifecycle3:rxlifecycle-components-preference:3.0.0'


// If you want to use Android Lifecycle for providers

implementation 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle:3.0.0'


// If you want to use Kotlin syntax

implementation 'com.trello.rxlifecycle3:rxlifecycle-kotlin:3.0.0'


// If you want to use Kotlin syntax with Android Lifecycle

implementation 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle-kotlin:3.0.0'


// If you want to use Navi for providers

// DEPRECATED: Use rxlifecycle-android-lifecycle instead. This will be removed in a future release.

implementation 'com.trello.rxlifecycle3:rxlifecycle-navi:3.0.0'





추가지원 라이브러리.

* Realm : 객체중심의 데이터베이스 라이브러리.

// https://realm.io/docs/java/latest


* glide : 이미지 로딩 라이브러리

   repositories {

       mavenCentral()

     google()

           }


     dependencies {

     implementation 'com.github.bumptech.glide:glide:4.8.0'

     annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'

     }


'Android > study' 카테고리의 다른 글

MVP 패턴  (0) 2019.04.25
안드로이드 액티비티 및 프래그먼트.  (0) 2018.09.27
레트로핏, okhttp  (0) 2018.08.27
RxJava  (0) 2018.07.30


코틀린 isNullOrBlank or isNullOrEmpty 테스트.


// 널 을 가지고 있는 스트링.
var nullString: String? = null

//공백체크.
println(nullString.isNullOrBlank()?.toString()) //output: true
//비어있는
println(nullString.isNullOrEmpty()?.toString()) //output: true

// 데이터를 가지고 잇는 스트링.
var helloString: String = "Hello"
println(helloString.isNullOrBlank()?.toString()) //output: false
println(helloString.isNullOrEmpty()?.toString()) //output: false

// 빈 문자열을 가지고 있는 스트링.
var blankString: String = ""
println(blankString.isNullOrBlank()?.toString()) //output: true
println(blankString.isNullOrEmpty()?.toString()) //output: true

// 공백을 가지고 있는 스트링.
var emptyString: String = " "
println(emptyString.isNullOrBlank()?.toString()) //output: true
println(emptyString.isNullOrEmpty()?.toString()) //output: false

// 공백을 가지고 있는 스트링.
var emptyString2: String = " ㅇㅇㅇ"
println(emptyString2.isNullOrBlank()?.toString()) //output: false
println(emptyString2.isNullOrEmpty()?.toString()) //output: false


'Kotlin > study' 카테고리의 다른 글

Retrofit, RxJava, AndroidProject  (0) 2019.01.30
코틀린 클래스.  (0) 2018.10.04
코틀린 apply,let 함수  (0) 2018.08.24

TabLayout _ 코틀린




탭레이아웃 사용하기


탭레이아웃을 사용하기 위한 디펜던시 추가.


프로젝트 생성 후 build.gradle(app) 아래 코드를 추가.


dependencies {

...

...

implementation 'com.android.support:design:x.y.z //추가.

}



3개의 프래그먼트를 뵤여주기 위해 탭 레이아웃 과 뷰페이저를 xml에 등록함.

//////////////////////////////////////////////////////////////////////////////////////////

xml 소스 구성.

activity_main.xml


상단 

//////////////////////////////////////////////////////////////////////////////////////////

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

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".activity.MainActivity">


    <android.support.design.widget.TabLayout


        android:id="@+id/tabLayout"

        android:layout_width="match_parent"

        android:layout_height="?android:attr/actionBarSize"

        app:layout_constraintBottom_toTopOf="@+id/viewPager"

        app:layout_constraintLeft_toLeftOf="parent"

        app:layout_constraintRight_toRightOf="parent"


        app:layout_constraintTop_toTopOf="parent"


        >


    </android.support.design.widget.TabLayout>



    <android.support.v4.view.ViewPager

        android:id="@+id/viewPager"

        android:layout_width="match_parent"

        android:layout_height="0dp"


        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintLeft_toLeftOf="parent"

        app:layout_constraintRight_toRightOf="parent"

        app:layout_constraintTop_toBottomOf="@+id/tabLayout">


    </android.support.v4.view.ViewPager>



</android.support.constraint.ConstraintLayout>

//////////////////////////////////////////////////////////////////////////////////////////


하단

//////////////////////////////////////////////////////////////////////////////////////////

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

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity">

    

    <android.support.v4.view.ViewPager

        android:id="@+id/viewPager"

        android:layout_width="match_parent"

        android:layout_height="0dp"

        app:layout_constraintBottom_toTopOf="@+id/tabLayout"

        app:layout_constraintLeft_toLeftOf="parent"

        app:layout_constraintRight_toRightOf="parent"

        app:layout_constraintTop_toTopOf="parent">

    </android.support.v4.view.ViewPager>


    <android.support.design.widget.TabLayout

        android:id="@+id/tabLayout"

        android:layout_width="match_parent"

        android:layout_height="?android:attr/actionBarSize"

        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintLeft_toLeftOf="parent"

        app:layout_constraintRight_toRightOf="parent"

        app:layout_constraintTop_toBottomOf="@+id/viewPager">

    </android.support.design.widget.TabLayout>


</android.support.constraint.ConstraintLayout>

//////////////////////////////////////////////////////////////////////////////////////////


뷰 페이저 안에 탭 레이아웃 포함.(상단.)

//////////////////////////////////////////////////////////////////////////////////////////

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

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".activity.MainActivity">



    <android.support.v4.view.ViewPager

        android:id="@+id/viewPager"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintLeft_toLeftOf="parent"

        app:layout_constraintRight_toRightOf="parent"

        app:layout_constraintTop_toTopOf="parent">



        <android.support.design.widget.TabLayout


            android:id="@+id/tabLayout"

            android:layout_width="match_parent"

            android:layout_height="?android:attr/actionBarSize">


        </android.support.design.widget.TabLayout>



    </android.support.v4.view.ViewPager>




//////////////////////////////////////////////////////////////////////////////////////////



MainActivity.kt 소스 작성.

탭레이아웃을 구성하기 위한 ui 정의 및 프래그먼트 데이터 생성.


class MainActivity : AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)


        setupUI()

    }


    //UI 초기화.

    private fun setupUI() {


        setupTabLayout()

    }


    // 탭 레이아웃 설정.

    private fun setupTabLayout() {


        val pageAdapter = MainViewPagerAdapter(setFragmentList(), supportFragmentManager)

        viewPager.adapter = pageAdapter


        tabLayout.setupWithViewPager(viewPager)


    }


    // 프래그먼트 리스트 설정.

    private fun setFragmentList(): List<Pair<Fragment, String>> {

//        val pageList = listOf(

//            Pair(MainFragment_1.newInstance(), "first"),

//            Pair(MainFragment_2.newInstance(), "first"),

//            Pair(MainFragment_3.newInstance(), "first")

//        )

//        return pageList


        return listOf(

            Pair(MainFragment_1.newInstance(), "first"),

            Pair(MainFragment_2.newInstance(), "second"),

            Pair(MainFragment_3.newInstance(), "third")

        )

    }


    // 프래그먼트 리스트 설정.

    private fun setFragmentList2() = listOf(

        Pair(MainFragment_1.newInstance(), "first"),

        Pair(MainFragment_2.newInstance(), "second"),

        Pair(MainFragment_3.newInstance(), "third")

    )


}

//////////////////////////////////////////////////////////////////////////////////////////

ViewPagerAdapter 소스(FragmentPagerAdapter)


class MainViewPagerAdapter(val pageList: List<Pair<Fragment, String>>, fragmentManager: FragmentManager) :

    FragmentPagerAdapter(fragmentManager) {



    override fun getItem(position: Int): Fragment {

        return pageList[position].first

    }


    override fun getCount(): Int {

        return pageList.size

    }


    override fun getPageTitle(position: Int): CharSequence? {

//        return super.getPageTitle(position)

        return pageList[position].second

    }


}

//////////////////////////////////////////////////////////////////////////////////////////


보여줄 프래그먼트 소스.



private const val ARG_PARAM1 = "param1"

private const val ARG_PARAM2 = "param2"



class MainFragment_1 : Fragment() {


    private var param1: String? = null

    private var param2: String? = null


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        arguments?.let {

            param1 = it.getString(ARG_PARAM1)

            param2 = it.getString(ARG_PARAM2)

        }

    }


    override fun onCreateView(

        inflater: LayoutInflater, container: ViewGroup?,

        savedInstanceState: Bundle?

    ): View? {


        return inflater.inflate(R.layout.fragment_main_fragment_1, container, false)

    }


    companion object {

        // param을 null로 처리하면 인자를 따로 추가 안해도 된다.

        // 인자값을 추가할 경우 해당 데이터가 저장된다.

        @JvmStatic

        fun newInstance(param1: String? = null, param2: String? = null) =

            MainFragment_1().apply {

                arguments = Bundle().apply {

                    putString(ARG_PARAM1, param1)

                    putString(ARG_PARAM2, param2)

                }

            }

    }

}


//////////////////////////////////////////////////////////////////////////////////////////

탭 레이아웃 기본 정리





















코디네이터레이아웃 사용해서 스크롤시 

툴바 및 리사이클러뷰 스크롤시 최상단 및 최하단 터치 감지가 불량일 때가 있다.

최상단 혹은 최하단 스크롤 후 리스트 항목을 클릭이 되지 않아 두번 클릭해야하는데 


안드로이드 sdk 28에서는 정상동작 한다.

이전 버전에서 AppBarLayout.Behavior 에 버그가 있는듯.



android coordinatorlayout recyclerview scroll click

이렇게 검색하니 스택오버플로우에 올라온 글

Click not working on RecyclerView in CoordinatorLayout when scrolling



코틀린 코드만 입력


게시글 중 해당 링크가 있고 수정된 코드 java와 kotlin이 있음.


https://gist.github.com/erikhuizinga/edf408167b46eb5b1568424563ca4e59


kotlin

//////////////////////////////////////////////////////////////////////////////////////////

/**

 * Workaround AppBarLayout.Behavior for https://issuetracker.google.com/66996774

 *

 *

 * See https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2 for

 * example usage.

 *

 * Kotlinised by Erik Huizinga (github: @erikhuizinga).

 */

class FixAppBarLayoutBehavior(context: Context?, attrs: AttributeSet?) :

AppBarLayout.Behavior(context, attrs) {


override fun onNestedScroll(coordinatorLayout: CoordinatorLayout, child: AppBarLayout,

                            target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int,

                            dyUnconsumed: Int, type: Int) {

super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed,

dyUnconsumed, type)

stopNestedScrollIfNeeded(dyUnconsumed, child, target, type)

}


override fun onNestedPreScroll(coordinatorLayout: CoordinatorLayout, child: AppBarLayout,

                               target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {

super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)

stopNestedScrollIfNeeded(dy, child, target, type)

}


private fun stopNestedScrollIfNeeded(dy: Int, child: AppBarLayout, target: View, type: Int) {

if (type == ViewCompat.TYPE_NON_TOUCH) {

val currOffset = topAndBottomOffset

if (dy < 0 && currOffset == 0 || dy > 0 && currOffset == -child.totalScrollRange) {

ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH)

}

}

}

}

//////////////////////////////////////////////////////////////////////////////////////////


코드 사용법 

AppBarLayout abl = findViewById(R.id.app_bar);

((CoordinatorLayout.LayoutParams) abl.getLayoutParams()).setBehavior(new FixAppBarLayoutBehavior());



xml 사용법

<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout

            android:id="@+id/app_bar"

            android:layout_height="..."

            android:layout_width="..."

            app:layout_behavior="your.package.FixAppBarLayoutBehavior">


    </android.support.design.widget.AppBarLayout>


    <!-- Content -->


</android.support.design.widget.CoordinatorLayout>






+ Recent posts