'어장 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
블로그 이미지

김생선

세상의 모든것을 어장관리

댓글을 달아 주세요