'어장 Develop/어장 Android'에 해당되는 글 5건

어플을 개발하다보면 아래와 같이 공지사항 형식의 dialog를 많이 볼 수 있다.





그러니까, 처음 실행시 해당경고사항에 대해 팝업을 띄워주고 다시보지 않음과 같은 버튼을 만들어서 해당 버튼을 클릭하면 다음부터는 실행하지 않는 것인데, 의외로 구현하기가 거시기한 항목중 하나였다.


간단히 말 해서, dialog와 SharedPreference를 함께 쓰는 것이었다.


sharePreference는 어플리케이션의 "설정"창에서 흔히 볼 수 있는 부분인데, 이에 대한 선행이해가 필요할 것이나, 무작정 따라해서 구현할 수도 있기 때문에 일단 적어본다.


개략적인 구성은 아래와 같다.


Preference 항목을 두 개를 만든다고 가정하자, 각각 A와 B 이다.

어플이 실행될 때 마다 A Preference에 어플 버전을 저장하고 dialog를 호출할 때 A Preference와 B(초기값 null) Preference를 비교하여, A와 B가 다르면 dialog를 보여준다.

[다시보지 않기] 버튼을 클릭할 경우, 어플리케이션 버전을 B Preference에 저장한다.


결론적으로 어플이 실행될 때 [다시보지 않기]를 클릭한 경우, 저장된 A와 B가 서로 같기 때문에 dialog를 출력하지 않는다.


만약 어플리케이션 버전업을 할 경우, A Preference에는 새로운 버전이 저장되며, B Preference에는 기존의 버전이 저장되기 때문에 A와 B가 다르고, 다르기 때문에 dialog를 다시 보여준다.


약간 이해가 어려울 지 모르겠지만 뭐 상관없다.


그럼 개략적인 소스를 살펴보자.


/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);


String version;

try {

PackageInfo i = getPackageManager().getPackageInfo(getPackageName(), 0);

version = i.versionName;

} catch (NameNotFoundException e) {

version = "";

}


SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE); // UI 상태를 저장합니다.

SharedPreferences.Editor editor = pref.edit(); // Editor를 불러옵니다

editor.putString("check_version", version); // 저장할 값들을 입력합니다.

editor.commit(); // 저장합니다.


String check_version = pref.getString("check_version", "");// 

String check_status = pref.getString("check_status", "");

if (!check_version.equals(check_status)) {

AlertDialog alert = new AlertDialog.Builder(this).setIcon(R.drawable.icon)

.setTitle(R.string.app_notice)

.setMessage(R.string.app_notice_update)

.setPositiveButton(R.string.app_notice_yes, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

}

})


    .setNegativeButton(R.string.app_notice_no, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

String version;

try {

PackageInfo i = getPackageManager().getPackageInfo(getPackageName(), 0);

version = i.versionName;

} catch (NameNotFoundException e) {

version = "";

}

SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE); 

   // UI 상태를 저장합니다.

SharedPreferences.Editor editor = pref.edit(); // Editor를 불러옵니다

editor.putString("check_status", version);

editor.commit(); // 저장합니다.

dialog.cancel();

}

}).show();

}

}



그럼 이제 소스를 차분히 뜯어보자.


String version;

try {

PackageInfo i = getPackageManager().getPackageInfo(getPackageName(), 0);

version = i.versionName;

} catch (NameNotFoundException e) {

version = "";

}


이 부분은 어플리케이션의 버전을 저장하는 부분이다. version 이라는 항목에 String 값으로 저장된다.



SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE); // UI 상태를 저장합니다.

SharedPreferences.Editor editor = pref.edit(); // Editor를 불러옵니다

editor.putString("check_version", version); // 저장할 값들을 입력합니다.

editor.commit(); // 저장합니다.


주석이 잘 달려있기 때문에 크게 설명할 부분이 없다.

check_version 항목에 현재 어플리케이션 버전을 저장한다.



String check_version = pref.getString("check_version", "");// 

String check_status = pref.getString("check_status", "");


여기서부터가 이제 중요하다.

저장된 check_versioncheck_status를 가져온다.

check_version은 윗부분에서 현재 어플리케이션을 저장했으며, check_status에서는 아무것도 저장되지 않았기 때문에 null값이 들어간다.



if (!check_version.equals(check_status)) {


check_version과 check_status를 비교한다. string 형이기 때문에 .equals로 비교를 하며, 서로 값이 다를 때를 가정하기 때문에 check_version 앞에 !를 붙인다.



AlertDialog alert = new AlertDialog.Builder(this).setIcon(R.drawable.icon)

.setTitle(R.string.app_notice)

.setMessage(R.string.app_notice_update)

.setPositiveButton(R.string.app_notice_yes, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

}

})


해당 부분은 dialog 부분이기 때문에 설명 없이 넘어간다.

해당 부분은 ok 버튼을 클릭했을 때를 나타낸다.



.setNegativeButton(R.string.app_notice_no, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {


[다시보지 않음] 항목을 클릭했을 때를 정의한다.



String version;

try {

PackageInfo i = getPackageManager().getPackageInfo(getPackageName(), 0);

version = i.versionName;

} catch (NameNotFoundException e) {

version = "";

}


현재 어플리케이션 버전값을 읽어오기 위한 version 체크 부분이다.



SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE); 

   // UI 상태를 저장합니다.

SharedPreferences.Editor editor = pref.edit(); // Editor를 불러옵니다

editor.putString("check_status", version);

editor.commit(); // 저장합니다.

dialog.cancel();


SharedPreference의 pref에 아래의 내용을 저장한다.

check_status에 위에서 호출한 version 값을 저장하고 dialog를 cancle 한다.




이로써 다시보지 않음 dialog를 정의하는 방법에 대해 알아보았다.

negative 버튼을 클릭하였을 때 현재 버전을 check_status에 저장하고, 어플리케이션을 다시 실행하였을 때, check_version과 check_status를 비교하여 같으면 보이지 않고, 다르면 보이는 코드는 이처럼 구현된다.


물론 중복되는 소스도 있고 확실히 좀 더 줄일 수 있는 부분이 몇군데 보이지만 현재로써는 내가 할 수 있는 부분은 이와 같다.

'어장 Develop > 어장 Android' 카테고리의 다른 글

[Android] addview를 사용할 때의 위치설정  (0) 2012.08.08
Thread로 ProgressDialog 사용하기  (0) 2012.08.03
listview와 intent  (0) 2011.03.16
listview  (0) 2011.03.12
블로그 이미지

김생선

세상의 모든것을 어장관리

,

어플리케이션을 개발하면서 addview를 사용하게 되었다.

addview란, 해당 activity가 호출하는 xml 레이아웃에 소스코드로 직접 view를 만들어서 add를 한다고 보면 된다.


간단히 소스를 보자.


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.sign);
		
		myView = new MyView(this);
		LayoutParams param;
		param = new LayoutParams(width, rowheight * 10);
		param.gravity = Gravity.BOTTOM;

		layout = (LinearLayout) findViewById(R.id.layout);
		layout.addView(myView, 1, param);

		findViewById(R.id.btnConfirm).setOnClickListener(this); // 확인
		findViewById(R.id.btnReSign).setOnClickListener(this); // 재서명
		
		GetScreenSize();
		ActivityInitialize();

	}

위와 같이 setContentView에서 sign 레이아웃을 호출하였고, 하단부에서 addview를 통하여 layout 하나를 더 호출한다.

그 결과, 아래와 같다.



밑의 버튼이 달린 부분이 xml로 작성된 레이아웃이고, 좀 더 진한 회색이 addview로 작성된 레이아웃이다.

그럼, 이 부분의 위치를 바꿀 수는 없을까?

버튼을 상단으로 위치하게 할 순 없을까?


방법은 별거없다.


layout.addView(myView, 1, param);


의 1을 0으로 주면 아래의 그림과 같이 변한다.


뭐 addview에 대해서는 좀 더 배워야 하니까, 여기까지 하자.

'어장 Develop > 어장 Android' 카테고리의 다른 글

공지사항 dialog  (2) 2012.09.26
Thread로 ProgressDialog 사용하기  (0) 2012.08.03
listview와 intent  (0) 2011.03.16
listview  (0) 2011.03.12
블로그 이미지

김생선

세상의 모든것을 어장관리

,



안드로이드 어플리케이션을 개발하면서 ProgressDialog를 쓰게 된다.

대부분 로딩화면에서 이 다이얼로그를 사용하는데, 매우 기초적인 다이얼로그의 경우, 작업이 끝나도 dismiss를 통한 수동 종료를 해주어야 하는 식으로 작업한다.


이럴 경우, 간단한 것에는 큰 문제가 없지만 로딩시 몇개의 개체가 불려왔는지에 대한 각종 부분을 보여주기 위해서는 thread를 통한 제어가 필요하다는 것이다.


뭐 여튼, 간단명료하게 설명을 해 보겠다.

ProgressDialog(); // ProgressDialog 호출

이 부분은 ProgressDialog를 호출하는 부분이다.

onCreate에 선언하여 로딩시 쓸 수도 있고, OnClickListener에 선언하여 클릭시 로딩 등에서도 사용이 가능하다.


나의 경우에는 아래와 같이 선언하였다.

	@Override
	public void onClick(View v) {
		String attendance;
		switch (v.getId()) {
		case R.id.btnReSign:
			ProgressDialog(); // 진행바 호출
			myView.reset();
			break;

		}
		finish();
	}



그럼 ProgressDialog();의 부분을 보자.

private ProgressDialog SaveUserSign; // Loading Dialog
	void ProgressDialog() {
		/* ProgressDialog */
		SaveUserSign = ProgressDialog.show(this, "김생선 어플", "저장중입니다.", true, false);

		Thread thread = new Thread(new Runnable() {
			public void run() {
				// 처리할 부분
				handler.sendEmptyMessage(0);
			}
		});
		thread.start();
	}

ProgressDialog이 SaveUserSign이란 이름으로 호출이 되고, SaveUserSign은 ProgressDialog를 .show에 주어진 메시지로 출력이 된다. 

그리고 Thread를 통하여 주석에 위치한 처리할 부분을 처리하고, 이 작업이 끝나면 handler를 호출한다. 

나의 경우, 주석의 위치에 사람들의 서명부분을 저장하고 서버로 올리는 작업을 추가했다. 



마지막으로 종료를 위한 handler부분을 살펴보자.

	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			SaveUserSign.dismiss(); // 다이얼로그 삭제
			// View갱신
		}
	};

handler부분은 SaveUserSign의 다이얼로그를 dismiss 해준다는 내용이 가장 크다.

그 외에 큰 어려움은 없으니 조금만 살펴보고 연구하면 다음엔 더 쉽게 구현할 수 있을 것 같다.

AsyncTask 방법을 사용하는 것도 있다는데... 흐미...

'어장 Develop > 어장 Android' 카테고리의 다른 글

공지사항 dialog  (2) 2012.09.26
[Android] addview를 사용할 때의 위치설정  (0) 2012.08.08
listview와 intent  (0) 2011.03.16
listview  (0) 2011.03.12
블로그 이미지

김생선

세상의 모든것을 어장관리

,
해당 내용은 개인적인 기록으로 질문을 일체 받지 않습니다.
알아두시기 바랍니다.

일전에 하나의 액티비티에서 여러개의 아이템을 가져오는 것에 대해 고민 한 적이 있었다.
요사이 바쁜 일이 많기에 좀처럼 코딩을 할 수 없었으나 시간이 나서 잠깐 해 보았다.


listview 에서 해당 아이템으로 intent를 보내는 과정.

  소스1
  1.     protected void onListItemClick(ListView l, View v, int position, long id) {
  2.     super.onListItemClick(l, v, position, id);
  3.    
  4.       if(position == 0){       
  5.         Intent intent = new Intent(this, page_one.class);
  6.         intent.putExtra("abc""kimfish");
  7.         startActivity(intent);
  8.       } 
  9.       else if(position == 1){
  10.             Intent intent = new Intent(this, page_one.class);
  11.         intent.putExtra("abc""bbbb");
  12.             startActivity(intent);
  13.       }
 

소스 1에서 리스트의 구현과 함께 position을 통하여 두 개의 아이템에 각각의 메시지를 전달해준다.
Intent intent = new Intent(this, page_one.class) 에서는 intent로의 이동을 의미한다고 볼 수 있는데, this(현재 클래스.this라 적어도 된다.)에서 page_one.class로 intent 값을 보낸다고 보면 된다. 
 

 intent.putExtra("abc""kimfish");를 보자면 abc란 값에 kimfish를 넣어서 putExtra로 보낸다.
그럼 다음 소스를 보자.


 소스2
  1. Intent intent = getIntent();
  2.          String str = intent.getStringExtra("abc");
  3.          TextView tv = new TextView(this);     //TextView 생성
  4.          tv.setText(str);                      //출력내용 지정
  5.          Log.i("abc"""+tv);
  6.          setContentView(tv);                   //Activity에 나타냄
 
소스1에서 보낸 intent를 getIntent가 받는다.
또한 소스1에서 abc에 kimfish를 넣어 보낸 값을 getStringExtra가 받게 된다.
이 abc에는 kimfish가 저장되어져 있으며 setText(str)값을 통하여 str를 출력, kimfish가 화면에 보이게 된다.

 
위의 내용은 리스트에서 
if(position == 0) 을 터치한 것에 대한 값 출력을 설명하였으나 else if(position == 1) 등을 터치했을 때에도 소스2에는 별다른 코드의 추가 없이 구현이 잘 된다.

참고로 Log.i("abc"""+tv); 는 abc가 잘 받아지는지에 대한 로그캣 출력값이다. 신경 안써도 된다.


이전에 해결한 문제점
2011/03/12 - [어장 안드로이드 프로그래밍] - listview
1. 이 포스트에서 다루듯이 해결.
2. 관련 내용이 아니기에 생략.
3. 소스1에서 내용을 보내기 때문에 for로 position값을 정해줄 수는 없다.
애초에 내가 생각한 것은 소스1에서 받은 position 값이 소스2 에서 받아지면서 이 position(예로 position == 0이면 소스2 에서 0을 받는 식) 값에 따라 해당 xml을 출력하는 방식이었다.
지금 생각해보면 왜 그딴 생각을 했는지 이해가 안된다.


또다시 생긴 문제점
1.
해당 내용을 보낼 때 소스2에서 xml값을 출력할 수는 없을까?
불러올 수 없다면 소스 1에서 많은 내용을 입력하고 많은 내용을 불러와야 할 뿐인가?  

2.
문제점은 아니지만 글 중간 중간에 사용자 키보드 입력을 받는 구간이 있을 것이다. 이제 이것을 구현하면 된다. 그런데 생각해보니 여러모로 1의 문제처럼 xml을 받는 것 보다는 직접 출력 하는 것이 더 좋지 않을까 한다.
이것에 대해서는 나중에 좀 더 생각해봐야 할 것 같다. 

'어장 Develop > 어장 Android' 카테고리의 다른 글

공지사항 dialog  (2) 2012.09.26
[Android] addview를 사용할 때의 위치설정  (0) 2012.08.08
Thread로 ProgressDialog 사용하기  (0) 2012.08.03
listview  (0) 2011.03.12
블로그 이미지

김생선

세상의 모든것을 어장관리

,
해당 내용은 개인적인 기록으로 질문을 일체 받지 않습니다.
알아두시기 바랍니다.

리스트뷰는 리스트를 보여준다.
리스트뷰에 관련된 이벤트들은 종류가 꽤 많다.
listiview
- onListItemClick
- onClickListener
등등

아래는 예시이다.
  1     private static final String[] GENRES = new String[] {
  2         "만만이", "kimfish"
  3     };
  4     
  5     protected void onListItemClick(ListView l, View v, int position, long id) {
  6     	  super.onListItemClick(l, v, position, id);
  7     	  if(position == 0){
  8     		  Intent intent = new Intent(list.this, mysecretnote.class);
  9     		  startActivity(intent);
 10     	  }
 11     	  else if(position == 1){
 12     		  Intent intent = new Intent(list.this, android1.class);
 13     		  startActivity(intent);
 14     	  }
 15     	  
 16     	  
 17 }
onListItemClick은 네 개의 피라미터를 가진다.
ListView I, View v, int positiob, long id 이렇게 네 개이다.
그 중, position을 이용하여 분기를 주면 인텐트로 하여금 해당 액티비티를 호출한다.

리스트는 여기에서 두 개로 보여진다.

만만이를 터치하게 되면 mysecretnote.class가 호출되고
kimfish를 터치하게 되면 kimfish.class가 호출된다.


앞으로 구현해아 할 점

1.
activity를 하나로 고정하고 리스트에서 해당 값을 불러올 수 있을까?
ex.
1~10 아이템 존재, kimfish.class 한 개 존재
1을 터치하면 kimfish 호출, 1에 관련된 내용 출력
.
.
.
10을 터치하면 kimfish 호출, 10에 관련된 내용 출력

2.
학교 열람실 정보를 출력하는 과정에서 해당 한글이 모조리 깨지는 것을 보아 관련 인코딩 문제가 있는 듯 하다.
파싱을 확실히 배워야 하는가?

3.
listview에서 onListItemClick을 호출할 때 해당 포지션값을 for로 입력할 수는 없는걸까?

'어장 Develop > 어장 Android' 카테고리의 다른 글

공지사항 dialog  (2) 2012.09.26
[Android] addview를 사용할 때의 위치설정  (0) 2012.08.08
Thread로 ProgressDialog 사용하기  (0) 2012.08.03
listview와 intent  (0) 2011.03.16
블로그 이미지

김생선

세상의 모든것을 어장관리

,