Rxjava와 MVVM 패턴을 사용한 영화 앱 강의를 듣던 중 유용해 보이는 플러그인을 발견해서 소개하려고 합니다.

 

플러그인 이름에서 볼 수 있듯이 Json 형식의 문자열을 코틀린 데이터 클래스로 쉽게 변환 해준다고 하네요.

 

간단한 사용법을 이미지와 함께 소개하겠습니당 ^0^

 

 

먼저 안드로이드 스튜디오 실행 후 File > Settings > Plugins 항목에서 json to kotlin 검색하여 설치하면

 

 

아래와 같이 새로운 파일 생성 시 "Kotlin data class File from JSON" 항목을 선택할 수 있습니다.

 

선택 후 Json 형식의 텍스트를 붙여넣기 해준 후에, 오른쪽 상단의 포맷 버튼을 눌러주면 붙여넣기로 인해 줄바꿈이 되어 있지 않던 Json 형식의 데이터가 보기좋게 정리됩니다. 하단의 Class Name에 원하는 클래스 명을 입력 하시면 그대로 데이터 클래스가 생성됩니다. 

 

 

추가적으로 설정하고 싶으신 옵션이 있으면 Advanced 버튼 클릭 후 둘러보세용..

 

짜잔 아주 간단하게 데이터 클래스가 생성된 모습 ^&^

 

오늘은 오준석님의 생존코딩 강의를 듣던 중 함수와 인터페이스의 색상을 구분하는 테마를 사용하고 계셔서

이참에 테마를 변경 했습니다.

 

적용하고나니 더 코드 읽기가 좋아진 것 같네요 ㅎㅎ

 

바로 본문으로 이동 하겠습니다.

 

안드로이드 스튜디오 테마 변경 방법

 

File > Settings > Appearance & Behavior > Appearance 이동 후 Theme 선택 해주시면 됩니다.

 

별도의 테마를 설치하지 않으신 분은 저처럼 테마가 여러개 나오지 않으실 겁니다. 

 

외부 테마를 사용하는 방법

 

Files > Settings > Plugins > "Material Theme UI" 검색

 

이 플러그인 설치 후 IDE를 재시작 하시면 위의 테마를 선택하는 부분에서 마음에 드는 테마를 선택하시면 됩니다.

 

제가 사용하는 Atom One Dark 테마는 인터페이스와 클래스를 구분하여 하이라이트 해주기 때문에 코드 읽기가 더 편한것 같아서 추천 드립니다!

 

이상으로 글 마치겠습니다!

앱 개발을 하던 도중에 EditText에 포커스가 가면 레이아웃 크기가 작아지는 현상이 발생했다. 

문제는 EditText에 포커스가 갈 때 올라오는 소프트 키보드가 레이아웃에 영향을 끼쳐서 크기가 작아지는 것 이었다..

 Manifest 파일에서 문제가 생기는 해당 액티비티 내에 아래의 옵션을 주면 키보드가 해당 액티비티의 레이아웃에

영향을 끼치지 않았다!

android:windowSoftInputMode="adjustNothing"

 

앱 개발 도중 앱 실행 중에 종료 후, 다시 시작할 때 튕기는 현상이 있었다. 로그인을 한 후에 재 시작했을 때 발생해서

로그인 관련 문제인가 싶어 시도 해보다가, 앱이 완전히 종료되지 않아서 발생하는게 아닌가 싶어서 시도 해 봤는데,

완전히 종료된게 아니기 때문에 발생한게 맞는 듯 싶다.

@Override
public void onBackPressed() { // DrawerLayout 이 열려있을 경우에는 DrawerLayout을 닫는다
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.END)) {
            drawer.closeDrawer(GravityCompat.END);
        } else {
            if(getSupportFragmentManager().getBackStackEntryCount() == 0)
            {
                moveTaskToBack(true); // 백그라운드로 전환
                finishAndRemoveTask();
                android.os.Process.killProcess(android.os.Process.myPid());
            }else
            {
               super.onBackPressed();
            }
        }
    }

주목 할 부분은 else 문 안에 if문 쪽이다. 나 같은 경우는 프래그먼트를 사용 했기 때문에, 만약에 프래그먼트가 메인 화면의 프래그먼트 일 경우(스택에 저장된 프래그먼트가 더이상 없을 경우) 앱을 완전히 종료하고, 아닐 경우는 backPressed를 실행 하도록 했다. 앱을 완전히 종료하고 나니 재 시작 했을 때도 튕기는 현상이 없어졌다!

공부를 위해 포스팅 된 글이므로, 부정확한 정보를 포함하고 있음을 감안하고 읽어주시기 바랍니다.

 

오늘은 구글 맵에서 기본적으로 제공되는 UI 버튼들을 커스텀 해서 사용하고, 활성화, 비활성화 

하는 작업을 했다.

 

https://developers.google.com/maps/documentation/android-sdk/controls 

 

Controls and Gestures  |  Maps SDK for Android  |  Google Developers

Using the Maps SDK for Android, you can customize the way in which users can interact with your map, by determining which of the built in UI components appear on the map and which gestures are allowed. Code samples The ApiDemos repository on GitHub include

developers.google.com

기본적으로 GoogleMap 객체에서 GetUISettings() 를 호출해서 버튼들을 얻어 올 수 있으나,

위치를 설정하기가 너무 불편해서 직접 레이아웃에 버튼을 생성하여 이벤트를 걸어줬다.

 

btn_myLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(mCurrentLocatiion.getLatitude(),mCurrentLocatiion.getLongitude())));
            }});
        btn_zoomIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { mGoogleMap.animateCamera(CameraUpdateFactory.zoomIn());}});
        btn_zoomOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { mGoogleMap.animateCamera(CameraUpdateFactory.zoomOut()); }});

 

    @Override
    public void onLocationChanged(Location location) {

        currentPosition
                = new LatLng( location.getLatitude(), location.getLongitude());


//        Log.d(TAG, "onLocationChanged : ");

        String markerTitle = getCurrentAddress(currentPosition);
        String markerSnippet = "위도:" + location.getLatitude()
                + " 경도:" + location.getLongitude();

        //현재 위치에 마커 생성하고 이동
        setCurrentLocation(location, markerTitle, markerSnippet);

        mCurrentLocatiion = location;
    }

 

 

공부를 위해 포스팅 된 글이므로, 부정확한 정보를 포함하고 있음을 감안하고 읽어주시기 바랍니다.

 

GoogleMapApi에서 CustomInfoWindow를 구현 하는데 Glide에서 가져온 이미지가 마커를 두번 클릭해야

이미지가 보여지는 버그를 발견했다. 이것저것 찾아본 결과, Glide에서 이미지를 가져오는 속도가 느려서

발생한 것일수도 있다고 생각해서 Glide에서 이미지를 가져오는 부분을 수정하니 잘 작동했다.

 Glide.with(context).
                load(SAMPLEURL + mapDataItem.getPLACE_IMAGE())
                .override(350,350)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .thumbnail(0.1f)
                .centerCrop()
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {

                        if (marker.isInfoWindowShown()) {
                            marker.hideInfoWindow();
                            marker.showInfoWindow();
                        }
                        return false;
                    }
                })
                .into(image);

        return view;
    }

비슷한 버그에 고생하는 사람이 줄었으면!!

이 글은 공부를 위해 작성된 글이므로 정확한 정보가 아닐 수 있음을 감안하고 읽어주시기 바랍니다.

 

오늘은 DB에서 얻은 위치정보를 이용하여 마커를 생성하도록 하는 기능을 추가시키는 중이었는데,

문제가 발생했다....

 

onResponse에서 얻은 값을 이용하여 바로 마커를 생성하도록 했는데,

마커를 찍는것은 UI 스레드에서 실행되어야 하는것이다.

서버에서 데이터는 OKHttp를 이용하여 받았는데 OKHttp의 onResponse는 메인 스레드에서 실행되지 않으므로

문제가 발생한 것이었다.

 

public void onSuccess(@Nullable String data) {
        Log.d("onSuccess",data + "얻은 값");
        
        // DB에서 얻은 값 파싱하여

        for(int i = 0; i < mapDataItems.length; i++)
        {
            final MarkerOptions  marker = new MarkerOptions()
                    .position(new LatLng(mapDataItems[i].getPLACE_COORD_X(),mapDataItems[i].getPLACE_COORD_Y()))
                    .title(mapDataItems[i].getPLACE_TITLE())
                    .snippet(mapDataItems[i].getPLACE_ADDRESS())
                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
                    
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mGoogleMap.addMarker(marker);
                }
            });


            }

나같은 경우는 마커를 찍는 부분만 메인 스레드에서 실행되도록 했다.

 

 

간단하게 해결하긴 했으나 이렇게 작성하는 것이 맞는지는 모르겠다.

하지만 이 코드를 사용하여 나는 원하는 결과를 얻었다.

+ Recent posts