posted by 므시칸곰틔군 2018. 7. 23. 17:36

시스템 환경설정에서

트랙패드 선택하고 추가 제스쳐에서 

페이지 쓸어 넘기기 체크한 후  '두 손가락으로 좌우로 스크롤 하기'

빼고 나머지 를 선택하면 파인더도 트랙패드에서 좌우로 제스쳐를 주면 뒤로가기 앞으로 가기

가 된다.



댓글을 달아 주세요

posted by 므시칸곰틔군 2018. 7. 17. 11:47

코틀린 MVP 패턴 적용 구현.

/**

 * 액티비티 상속 클래스

 */

abstract class BaseActivity : AppCompatActivity() {


    /**레이아웃 뷰 추상화 등록*/

    protected abstract val layoutId: Int


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(layoutId)

    }

}



// Contract.view 에 인터페이스를 받음.

class MainActivity : BaseActivity(), MainActivityContract.View {


    //BaseActivity에서 상속받은 변수.

    override val layoutId = R.layout.activity_main


    //뷰에 지정한 프레젠터 등록.

    override val presenter: MainActivityContract.Present = MainActivityPresenter()


    //뷰에서 상속받은.... ui 등록

    override fun initUi() {



    }


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)





    }

}



class MainActivityContract {

    /**

     * 단순 화면 처리

     * 액티비이에서 뷰 구현

     */

    interface View {


        /** 뷰에 프레젠터 등록.*/

        val presenter: Present


        /** Ui 초기화*/

        fun initUi()


    }


    /**

     * 프레젠터 뷰와 모델의 데이터 처리

     * 프레젠터 클래스를 생성하여 인터페이스 구현.

     */

    interface Present {


        /**프레젠터에 뷰 등록*/

        var view: View?


        /** 전달받을 뷰를 등록함.*/

        fun attachView(view: View)


        /** 뷰 해제*/

        fun detachView()


    }


}



/**

 * 데이터를 처리하는 프레젠터

 * 처리된 결과를 등록한 뷰에 전달.

 */

class MainActivityPresenter : MainActivityContract.Present {


    //뷰 초기화

    override var view: MainActivityContract.View? = null


    //뷰 지정.

    override fun attachView(view: MainActivityContract.View) {

        this.view = view

    }


    //뷰 해제

    override fun detachView() {

        this.view = null

    }

}



댓글을 달아 주세요

posted by 므시칸곰틔군 2018. 6. 8. 14:15

이걸 주석.하면 되고..

#skip-name-resolve=1

웹서버 도큐먼트루트 변경은 여기서 

Applications/mampstack-7.1.18-1/apache2/conf/bitnami/bitnami.conf


여기 수정.

 DocumentRoot "/Users/(USER)-pc/Web" 

  <Directory "/Users/(USER)-pc/Web">

댓글을 달아 주세요

posted by 므시칸곰틔군 2018. 6. 5. 09:19

안드로이드 베이스액티비티

프래그먼트 등록 및 액티비티 전환 메서드.

안드로이드 퍼미션 대응 


public abstract class BaseActivity extends AppCompatActivity {



    @Override

    public void onBackPressed() {


        if (getSupportFragmentManager().getBackStackEntryCount() == 0) {


            //뒤로가기 2초 종료 유도

            super.onBackPressed();

        } else {

            super.onBackPressed();

        }



    }


    /**

     * add 를 했을 때 액티비티에서 종료를 하면 앱이 0으로 표시된다.

     */

    public void addFragment(int id, Fragment fragment) {

        addFragment(id, fragment, null);

    }


    public void addFragment(int id, Fragment fragment, String tagName) {

        getSupportFragmentManager().beginTransaction().add(id, fragment, tagName).commit();

    }


    /**

     * 프래그먼트 전환.

     * 액티비티에서 앱을 종료하면 이건 1이 된다.

     */

    public void replaceFragment(int id, Fragment fragment) {

        replaceFragment(id, fragment, null);

    }


    public void replaceFragment(int id, Fragment fragment, String backStackName) {


        getSupportFragmentManager().beginTransaction().replace(id, fragment)

                // 백스텍에 이름이 없거나 널이면 프래그먼트클래스 이름을 등록

                .addToBackStack(backStackName).commit();

    }



    public void removeFragment(Fragment fragment) {


        getSupportFragmentManager().beginTransaction().remove(fragment).commit();

    }


    public void removeFragment(Fragment fragment, String backStackName) {


        getSupportFragmentManager().beginTransaction().remove(fragment)

                // 백스텍에 이름이 없거나 널이면 프래그먼트클래스 이름을 등록

                .addToBackStack(backStackName).commit();

    }


    /**

     * 액티비티 전환

     */

    public void changeActivity(Context context, Class<?> activity, boolean activityFinish) {


        Intent intent = new Intent(context, activity);


        startActivity(intent);

        if (activityFinish) {

            finish();

        }

    }



    /**

     * 퍼미션 체크 인터페이스

     */

    public interface PermissionCheckListener {

        /**

         * 퍼미션 허용이 끝나면 끝나는 시점 초기화 시작구간을 콜백으로 구현

         * 어디서든 등록하고 액티비티에서 콜백으로 지정을 한다

         */

        void permissionCheckFinish();

    }


    private PermissionCheckListener permissionCheckListener;


    public PermissionCheckListener getPermissionCheckListener() {

        return permissionCheckListener;

    }


    /**

     * 제일 먼저 등록

     */

    public void setPermissionCheckListener(PermissionCheckListener permissionCheckListener) {

        this.permissionCheckListener = permissionCheckListener;

    }


    /**

     * 퍼미션 권한 리퀘스트 코드

     */

    private final int PERMISSION_REQUEST = 11000;


    /**

     * 스트링 배열로 퍼미션 체크.<p>

     * true 면 퍼미션 승인 안한 것이 존재함<p>

     * onRequestPermissionsResult 로 넘어감

     */

    public boolean permissionCheck(String[] strings) {

        boolean check = false;


        // //안드로이드 마시멜로 이후 퍼미션 체크.

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


            for (int i = 0; i < strings.length; i++) {

                if (ContextCompat.checkSelfPermission(this, strings[i]) == PackageManager.PERMISSION_DENIED) {

                    ActivityCompat.requestPermissions(this, strings, PERMISSION_REQUEST);

                    check = true;

                    break;

                }

            }

        }

        return check;

    }



    @Override

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {


        super.onRequestPermissionsResult(requestCode, permissions, grantResults);


        if (requestCode == PERMISSION_REQUEST) {


            //LogUtil.e("권한 허용이 안된것을 확인해야한다..");

            // //안드로이드 마시멜로 이후 퍼미션 체크.

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


                for (int i = 0; i < grantResults.length; i++) {

                    if (grantResults[i] == 0) {

                        //LogUtil.w("권한이 승락된 것은 ??? " + permissions[i]);


                        if (grantResults.length == (i + 1)) {

                            //LogUtil.e("인터페이스로 한곳에 모아서 앱을 실행하도록 한다...");

                            // 앱 시작구간이라고 보면 된다

                            permissionCheckListener.permissionCheckFinish();

                        }


                    } else {

                        //LogUtil.w("권한 거절 것은 ??? " + permissions[i]);


                        // 거부한 이력이 있으면 true를 반환한다.

                        if (shouldShowRequestPermissionRationale(permissions[i])) {

                            //LogUtil.e("사용자가 다시 보지 않기에 체크를 하지 않고, 권한 설정을 거절한 이력이 있는 경우");

                            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST);

                            break;


                        } else {

                            //LogUtil.e("사용자가 다시 보지 않기에 체크하고, 권한 설정을 거절한 이력이 있는 경우.");


                            new AlertDialog.Builder(this).setTitle("다시보지않기 클릭.").setMessage(permissions[i] + " 권한이 거부되었습니다 설정에서 직접 권한을 허용 해주세요.").setNeutralButton("설정", new DialogInterface.OnClickListener() {

                                @Override

                                public void onClick(DialogInterface dialog, int which) {

                                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

                                    intent.setData(Uri.parse("package:" + getPackageName()));

                                    startActivity(intent);

                                    Toast.makeText(getApplicationContext(), "권한 설정 후 다시 실행 해주세요.", Toast.LENGTH_SHORT).show();

                                    finish();

                                }

                            }).setPositiveButton("확인", new DialogInterface.OnClickListener() {

                                @Override

                                public void onClick(DialogInterface dialog, int which) {

                                    Toast.makeText(getApplicationContext(), "권한 설정을 하셔야 앱을 사용할 수 있습니다.", Toast.LENGTH_SHORT).show();

                                    finish();

                                }

                            }).setCancelable(false).create().show();

                        }// shouldShowRequestPermissionRationale /else

                    } // 권한 거절

                } // for end

            }//Build.VERSION.SDK_INT  end

        }//requestCode  end

    }

}



MainActivity

public class MainActivity extends BaseActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        setPermissionCheckListener(new PermissionCheckListener() {
            @Override
            public void permissionCheckFinish() {
                // 앱 시작구간

            }
        });
// 체크 구문 예시//
        if (permissionCheck(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE})) {
            return;
        }

        getPermissionCheckListener().permissionCheckFinish();

    }
}





댓글을 달아 주세요

posted by 므시칸곰틔군 2018. 6. 4. 13:56
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

//RxJava,RxAndroid
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'

// 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)

//RxJava,RxAndroid
implementation 'io.reactivex.rxjava2:rxjava:2.x.x'

//RX 액티비티와 프래그먼트의 라으프사이클을 사용할수 있게해줌

//구독중 발생할수 있는 메모리 누수를 방지하기 위함
implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'

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

//Android 관련 라이프 사이클에 바인딩하려는 경우
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'

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

// 미리 작성된 활동 및 단편을 원할 경우 공급자로 하위 클래스화할 수 있습니다.
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'

// If you want to use Android Lifecycle for providers

// 공급자를 위해 Android 라이프 사이클을 사용하려는 경우
implementation 'com.trello.rxlifecycle2:rxlifecycle-android-lifecycle:2.2.1'

// 사용안함

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

// // 미리 작성된 지원 환경 설정을 원할 경우 공급자로 하위 클래스화할 수있는 조각

// implementation('com.trello.rxlifecycle2:rxlifecycle-components-preference:2.2.1') {

// exclude group: 'com.android.support'

// }

// 사용안함

// // If you want to use Navi for providers

// // 공급자에 Navi를 사용하려는 경우

// implementation 'com.trello.rxlifecycle2:rxlifecycle-navi:2.2.1'

// 코틀린 관련

// If you want to use Kotlin syntax

// Kotlin 구문을 사용하려는 경우

// implementation 'com.trello.rxlifecycle2:rxlifecycle-kotlin:2.2.1'

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

// Android 라이프 사이클에서 Kotlin 구문을 사용하려는 경우

// implementation 'com.trello.rxlifecycle2:rxlifecycle-android-lifecycle-kotlin:2.2.1'

// 이건 에러 상황이 발생되었을 때

// (){

// exclude group: 'com.android.support'

// }

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

//안드로이드 퍼미션 관련 라이브러리
implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'

//RxBinding

//각종 view 들의 이벤트를 옵저버로 형태로 변환하여 편하게 사용 가능함. //연속 클릭 방지를 위한 RxBiding 사용

// RxJava binding APIs for Android UI widgets from the platform and support libraries.
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'

// 'support-v4' library bindings:
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.1.1'

// 'appcompat-v7' library bindings:
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'

// 'design' library bindings:
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'

// 'recyclerview-v7' library bindings:
implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.1.1'

// 'leanback-v17' library bindings:

// implementation ('com.jakewharton.rxbinding2:rxbinding-leanback-v17:2.1.1'){

// exclude group: 'com.android.support'

// }

// Retrofit : restapi helper
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'

// gson
implementation 'com.google.code.gson:gson:2.8.2'

// OkHttp
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'








implementation 'com.android.support:recyclerview-v7:26.1.0'


댓글을 달아 주세요