https://github.com/wasabeef/awesome-android-ui

안드로이드 UI/UX개발 시 참고할 수 있는 git 페이지.

각 라이브러리 링크와 라이센스, 데모 움짤 등으로 이루어져있고, 업데이트도 충실한 편입니다.

Posted by 안드로메다에서 온 프로그래머

안드로이드에서 텍스트뷰를 사용해 보면 텍스트 뷰 내뷰에 기본 패딩이 있어

디자인 요구사항을 정확히 반영할 수 없는 경우가 있습니다.

다음과 같이 패딩을 제거해 줄 수 있습니다.


xml에서 적용

<TextView
    android:id="@+id/textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:includeFontPadding="false"/>
cs



코드에서 적용

java

textView.setIncludeFontPadding(false);
cs


c#

textview.SetIncludeFontPadding(false);
cs


코드나 xml 중 한 곳만 적용해 주면 됩니다.

적용한 모습이 기본 패딩이 사라진 텍스트뷰인데 이래도 요구사항에 맞지 않는다면,

추가로 마이너스 패딩을 주는 방법 등도 있으나 추천하는 방법은 아닙니다.



16년 12월 추가 : android:includeFontPadding="false" 가 Default 로 이미 적용되어 있는 경우도 있는 것 같습니다. 패치로 인한 것인지 특정 상황에서 그런 것인지는 아직 확인하지 않았습니다. 애매한 건 명시적으로 코딩하는게 좋으니 확인시까진 매번 false로 설정할 생각합니다.


참고 : https://developer.android.com/reference/android/widget/TextView.html


Posted by 안드로메다에서 온 프로그래머
final View view = View;
...
view.post(new Runnable() {
            @Override
            public void run() {
                view.getHeight(); //height is ready
            }
        });

Java에서는 new Runnable등을 이용해 익명 클래스를 사용할 수 있습니다.

하지만 C#은 '일단은' 익명 클래스를 허용하지 않습니다. 

그럼 이런 코드는 Xamarin.Android에서는 어떻게 사용할까요?


private IRunnable fRunnable;

view.Post(fRunnable);

fRunnable = new Runnable(() => {

    view.Height;

});

일단 이런 식으로 IRunnable를 사용해서 뭔가 기분은 이상하지만 일단 구현은 가능합니다(..) 

당장 급하실때만 사용 해 주세요.


Posted by 안드로메다에서 온 프로그래머

Manifests

Xamarin.Android의 Manifests설정은 Java와 약간, 아니 좀 많이 다릅니다.

Java Manifests의 <activity ~ /> 부분이 아래와 같이 사실상 각 cs파일 상단에 들어간다고 생각하시면 됩니다.

[Activity(Label = "자마린 ㄴㄴ", MainLauncher = true, Icon = "@drawable/icon")]

Xamarin으로 Android를 처음 만난 분을 위해 설명하자면,

Lable은 액티비티의 타이틀, MainLauncher는 앱 시작 페이지를 이 액티비티로 지정(당연히 true지정된 액티비티는 한 앱에 하나만 존재해야 합니다, Icon은 액티비티의 아이콘입니다.


Button

//버튼 선언

Button button = FindViewById<Button>(Resource.Id.Button);

//클릭 이벤트 등록은 자바의 리스너가 아닌 Event방식을 사용합니다

//이벤트 등록 방식 1번 button.Click += (object sender, EventArgs e) => {     Console.WriteLine("button이 눌러졌습니다"); //로그에 찍힙니다. log.d도 가능. };


//이벤트 등록 방식 2번, delegate를 이용해 간단한 처리를 한줄에 구현합니다.

button.Click += delegate { Console.WriteLine("button이 눌러졌습니다"); };


//이벤트 등록 방식 3번, OnCreate등에서 이벤트 메소드만 지정하는 방식입니다

//여러 버튼이 하나의 동작을 공유하는 것도 가능합니다

button.Click += button_Click;

void button_Click(object sender, EventArgs e)

{

//동작

}


//응용. 리스트뷰의 경우.

listView.ItemClick += delegate(object sender, AdapterView.ItemClickEventArgs e) \

{

//응용2. 클릭된 아이템의 text를 얻는다. custom ListView일 경우에는

//GetItemAtPosition의 재정의가 필요.

String text = listView.GetItemAtPosition(e.Position);

};


Dialog

//translatedNumber이라는 변수에 저장된 번호로 전화거는 다이얼로그 예제

var callDialog = new AlertDialog.Builder(this);

callDialog.SetMessage("Call" + translatedNumber + "?");//이 번호로 전화할건가?셋 메세지 callDialog.SetNeutralButton("Call", delegate {     var callIntent = new Intent(Intent.ActionCall);//전화 인텐트 callIntent.SetData(Android.Net.Uri.Parse("tel:" + translatedNumber)); StartActivity(callIntent); });


//List형식의 다이얼로그 예제


string[] titleMenu = { "사과", "메론" };

AlertDialog.Builder alert = new AlertDialog.Builder(activity);

alert.SetTitle("먹을 과일 선택"); //제목

alert.SetItems(titleMenu, (o, e) => //object, sender

{ // ↑ string xml 파일의 리스트를 여기에 써 줘도 됩니다.

//사과0,메론1

if (e.Which == 0)

{

System.Console.WriteLine("사과를 먹었습니다");

}

else if (e.Which == 1)

{

System.Console.WriteLine("메론을 먹었습니다");

}

});

alert.Show();


//다이얼로그 밖을 터치해서 닫을 수 있는 다이얼로그

//당연히 그런 거 아니야? 라고 생각할 수 있지만, Create 없이 그냥 바로 생성하면

//일부 안드로이드 버전에선 잘 되는데 일부에선 해당 기능이 동작하지 않는다....

//고객에게 간 버전에서만 안 될수 있다는 이야기.

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.SetTitle("정말 삭제하시겠습니까?");

builder.SetPositiveButton("예", delegate{ //positive work });

builder.SetNegativeButton("아니오", delegate { });

AlertDialog alert = builder.Create();

alert.SetCancelable(true);//취소 가능한 다이얼로그로 설정

alert.SetCanceledOnTouchOutside(true);//화면 밖을 터치해서 취소가 가능하게 설정

alert.Show();



다이얼로그 참조 링크 여기


기타 Java로 Android 개발하던 개발자가 C#으로 개발할 때 헷갈릴만한 사항들 메모.


커스텀 레이아웃 네임스페이스는 apk/res 가 아닌 apk/lib를 써야 한다

xmlns:yourApp="http://schemas.android.com/apk/lib/com.yourAppPackege.yourClass"


xml에서 커스텀 레이아웃을 사용할때는 네임스페이스를 사용해야 한다

패키지.경로.클래스명

EAppAndroid.Protype.LeftDrawerMenu2 

<EAppAndroid.Protype.LeftDrawerMenu2.OpendCheckLinearLayout



프래그먼트에서 어레이 어댑터 만들기

 ArrayAdapter adapter = new ArrayAdapter<string>(Activity,Android.Resource.Layout.SimpleListItem1, items);

다음과같이 this가 아닌 Activiti로 해줘야 한다

참고 http://arteksoftware.com/androids-built-in-list-item-layouts/

Posted by 안드로메다에서 온 프로그래머

Google Dvelopers - Training

http://developer.android.com/training/index.html

 

Google Dvelopers - BitmapFactory class

http://developer.android.com/reference/android/graphics/BitmapFactory.html

 

녹두장군님 블로그 - 비트맵을 스케일 조정하여 로딩

http://mainia.tistory.com/468

 

커니의 안드로이드 이야기 - 안드로이드의 파일 입출력에 필요한 경로를 얻는 방법 총정리

http://androidhuman.tistory.com/432

 

카메라 호출 후 넘어오는 intent.getData()가 null이거나 썸네일 Bitmap일결우 해결법

http://japanescape.tistory.com/14

원본포스팅

http://blog.naver.com/free2824/60199479410

위 포스팅의 문제점 : 4.4 킷켓에선  Ex메모리 권한 없음,

내장메모리 사용해야 함. 그런데 카메라는 외부 App 이므로 해당 App 내장영억 접근 권한이 없음

Posted by 안드로메다에서 온 프로그래머

안드로이드 개발 중

어떤어떤 상황에 키보드를 숨기자..라는 경우가 있다


예를 들어 입력창 이외에 빈 화면을 클릭해 주면 키보드가 사라진다던지,

다른 화면으로 이동하면 사라진다던지.


이런 경우에는 아래의 키보드 숨기기 코드를 알맞게 넣어주면 된다


우선 키보드를 숨길 곳에서 import 해준다

import android.view.inputmethod.InputMethodManager;


그리고 인풋매니저를 선언해준다

private InputMethodManager ipm;

꼭 프라이빗일 필요는 없다


생성자에서 객체화해준다

ipm= (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);


이제 사용하면 된다

ipm.hideSoftInputFromWindow(가져갈 화면.getWindowToken(), 0);

여기서 가져갈 화면이란, 클릭한 곳을 넣어주면 된다

만약에 온리섬이나 액티비티 스타트 지점 등 막 시작된 지점에선 위 코드가 제대로 동작하지 않을 수 있다

또는 가져갈 화면이(포커스할 지점)없는 경우도 있다

그럴때는 위 소스 대신

ipm.toggleSoftInput( 0, 0 );

라는 소스를 써줘도 된다


그러니까 키보드가 떠있는데 특정 리니어 레이아웃 구역을 누를시 키보드가 사라지게 하고 싶다면

해당 리니어 레이아웃을 선언한뒤 객체로 만들어서,

해당 객체.setOnTouchListener(new OnTouchListener() { });

이렇게 온터치리스너 따위에다가 위의 코드를 넣어주면 된다


예제

import android.view.inputmethod.InputMethodManager;


private InputMethodManager ipm;

private LinearLayout lin;


ipm= (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

lin = (LinearLayout) findViewById(R.id.lin);


lin.setOnTouchListener(new OnTouchListener() {


ipm.hideSoftInputFromWindow(lin.getWindowToken(), 0);

//또는(위 코드가 동작하지 않는 곳이나 마땅히 포커스할 lin이없는 경우에는

//ipm.toggleSoftInput( 0, 0 );

//하지만 토글소프트 인풋의 경우, 키보드를 무조건 사라지게 하는게 아니라

//현재 상태의 반대로 만든다, 그러므로 무조건 사라지게 하고 싶다면 위 코드를 쓸것


});


이렇게 했는데 안되는 경우가 있다.

바로 온 크리에이트,리섬,스톱 중에 넣어주는 경우인데, 이럴때는 약간의 딜레이를 줘야 한다

   Timer timer = new Timer();

   timer.schedule(new TimerTask() {

       @Override

       public void run() {

           ipm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

           ipm.hideSoftInputFromWindow(포커스를줄객체명.getWindowToken(), 0);

            }

       }, 100);



자마린 - fragment OncreateView내에서 사용시 (InputMethodManager는 import해줘야함)

InputMethodManager manager = (InputMethodManager)this.Activity.GetSystemService(Context.InputMethodService);


rlayout.Touch += (s, e) => { manager.HideSoftInputFromWindow(rlayout.WindowToken, 0); };


그외상황

http://stackoverflow.com/questions/14991071/hide-keyboard-programmatically-in-monodroid





자마린- 메소드로 편하게 쓰기


1. 키보드 숨기기 메소드 추가

public void HideKeyboard(View view) {

   InputMethodManager manager = (InputMethodManager)GetSystemService(Activity.InputMethodService);

   manager.HideSoftInputFromWindow(view.WindowToken, 0);

}


mainLayout.Touch += (s, e) => { HideKeyboard((LinearLayout)s); };



Posted by 안드로메다에서 온 프로그래머

커스텀 리스트뷰 (listview) 새로고침(갱신)

커스텀 리스트뷰를 새로고침,그러니까 갱신을 하려고 아래와 같은 방법을 사용했다


Adaptername.clear();

Adaptername.remove(datavo);

listviewname.clearChoices();

Adaptername.notifyDataSetChanged();

Adaptername.notifyDataSetInvalidated();

HelloActivity.this.onRestart();

HelloActivity.this.reset();

listviewname.setAdapter(Adaptername);


결과적으로 어떻게 해야 하냐면


다 안된다


어탭터를

cusorAdapter를 사용하고

notifyDataSetChanged() 대신 changeCursor()을 사용해야 한다

API11부터 사용할 수 있다고 한다


결론  : 오늘은 하루종일 삽질을 했다


커서어댑터를 사용하지 않고 해결하는 방법

1.커스텀 리스트 뷰의 아답터에 데이터리스트를 연결하는 부분을 메소드로 만든다

2.리스트 뷰를 갱신해줘야 하는 경우에 해당 메소드를 사용한다

..이렇게 단순하게 해결할 수 있다. 대체 몇시간을 삽질한건지

괜히 notifyDataSetChanged 라는게 있으니까 그걸 사용해보고 싶어서 그랬는데,

커스텀 뷰에는 안되니까 이 글을 보신 분은 위처럼 단순하게 해결하면 된다. 

(삭제 구현시에는 해당 리스트 아이템을 remove해주는 방법은 있다)

프로그래머는 단순하게 생각해야 한다는걸 다시 깨달았다.


*리플로 인해 좀 더 간단하게 정리

리스트를 첫 초기화 시키는 부분을 메소드로 만들어

데이터가 들어오면 초기화를 다시 시킴.


Posted by 안드로메다에서 온 프로그래머
1. XML Layout에서 TextView 속성에 android:scrollbars="vertical" 을 추가해 줍니다.

2. Activity의 OnCreate에서 TextView를 초기화 한 후 아래와 같이 처리해줍니다
     textView.setMovementMethod(new ScrollingMovementMethod());

예외. TextView가 ScrollView 안에 포함되었을 경우에는 아래와 같이 처리해줘야 합니다
     textView.setOnTouchListener(new OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
        ScrollView.requestDisallowInterceptTouchEvent(true);
        //스크롤뷰가 텍스트뷰의 터치이벤트를 가져가지 못하게 처리
        return false;
        }

   });


Posted by 안드로메다에서 온 프로그래머