블로그 이미지
엡뽀
피난(?) 오신걸 환영합니다.

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2013. 11. 8. 11:26 Programing/Android

Android GCM(Google Cloud Messaging)를 이용하여 데이터를 보내기 위해


GCMRegistrar.register(Context, SENDER_ID); 를 호출할때 오류가 나타나는 단말기가 있었습니다.

해당 오류는 단말기의 시간이 표준시간과 달라서 발생하는 오류였으며, 


Wifi 전용 단말기에서 재부팅되었을때, 표준시간 동기화가 정상적으로 일어나지 않아

단말기 시간이 '2004-01-10' 으로 설정되어 나타나는 문제였습니다.






posted by 엡뽀
2013. 10. 1. 15:55 Programing/Android

어느날 심심해서 git-hub에서 검색해본 Android 관련 오픈 소스입니다.
나중에 시간 내서 짬짬이 해보는 것도 재미있을것같아 기록해 둡니다.

MultiChoiceAdapter 

SwipeToDismissUndoList




posted by 엡뽀
2013. 2. 21. 11:23 News



출처 : http://www.theverge.com/2013/2/20/4008180/google-glass-ui-previewed-in-new-video


구글 글래스의 실제 프리뷰 영상이 유투브에 등록되었습니다. 구글 보이스로 영상을 찍거나 웹검색을 지원 한다고 합니다.

=========================================================================================


이것으로 또 다른 혁명의 시작이겠군요...

'News' 카테고리의 다른 글

카카오톡 게임 "다함께 차차차" 표절 논란?  (0) 2013.01.16
posted by 엡뽀
2013. 1. 16. 10:03 News

몇일전 소니에서 CJ E&M 넷마블에서 서비스 중인 다함께차차차 게임을 표절로 서비스 중지 요청이 있었습니다.

(기사 원문 : http://www.seoul.co.kr/news/newsView.php?id=20130115500001&ref=nc)


이에 따른 CJ E&M 넷마블측에서는 서비스 중단은 없을것이며, 소니의 법적대응에도 강경히 맞설 것이라고 합니다.

(기사 원문 : http://media.daum.net/digital/newsview?newsid=20130115115506454)



==============================================================================================


한명의 개발자로써 나의 결과물(지적 소유권)이 중요하듯이 다른 사람의 결과물(지적 소유권)이 중요 한건 당연한 것일텐데

"난 모르오" 식의 대응은 정말 양심없는게 아닐까합니다. 


협상을 통해 서비스는 이어가더라도, 표절과 관련해서는 CJ E&M에서의 명확한 해명이 필요하지 않을까요?


'News' 카테고리의 다른 글

구글 글래스 실제 작동영상  (0) 2013.02.21
posted by 엡뽀
2013. 1. 3. 20:31 Programing/Android

안녕하세요. 블로거 엡뽀입니다. 


지난 Android UI 만들기 포스팅을 하면서 오픈 소스를 사용한 일이 있었는데, GitHub 사용법을 몰라서 그저 무식하게 파일 복사, 붙여넣기로 포스팅을 진행하였습니다. 하지만 쪼금만 알아보니 이렇게 번거롭게 할 필요없이. 간단하게 오픈 소스를 사용하는 방법을 알게 되어 GitHub에 관한 간단한 포스팅과 오픈 소스 프로젝트 (android-view-flow)를 내 프로젝트에 추가하여 빌드 하는 포스팅을 하도록 하겠습니다. 



1. GitHub 


GitHub를 설명하기 전에 앞서, Git에 관하여 설명을 하겠습니다. Git란 분산저장소로 일종의 저장소라고 보시면 됩니다. 마치 웹하드 처럼  특정 컴퓨터(서버)에 파일을 저장하는 저장소의 일종입니다. 


본래 Git는 리눅스 OS의 기능으로, 여러가지 명령어를 이용하여, 파일들을 다른 서버로 저장하던가, 내 컴퓨터로 다운을 받던가, 내컴퓨터에 있는 파일을 업로드 등등 여러가지 작업을 할 수 있습니다.  다만 이러한 일련의 작업들이 터미널 창을 이용하여 명령어로만 이루어 진다는 것이죠. 또한 리눅스 OS이기에 윈도우에선 사용 할 수 없습니다. (하지만 사실, 윈도우용 Git도 나온 상태입니다.) 이러한 Git 기능을 쫌더 편리하고 운영체제 상관없이 동작 하게 하는 웹서버에서 동작하는 Git가 바로  GitHub가 아닌가 합니다. => 그저 막연한 추측입니다. 


결론적으로 한 프로젝트를 여러 개발자들이 개발을 하여 파일 SVN(Subversion)을 할 수 있도록 하여주는 기능이 Git 같습니다. 

(제가 참고 하였던 블로그엔 SVN 개념이 Git를 이해하는데 방해한다고 하던데; 제가 Git에 대한 명확한 개념이 잡히지 않아  저말 말고는 표현하기가 힘드네요;;)


그리고 이러한 Git 명령어들을 간편하게 이용할 수 있는 웹사이트가 GitHub 입니다. 즉 단순히 오픈 소스를 사용하기만 하거나 소스 분석만 할 경우에는 이클립 + Git 연동이 전혀 필요가 없습니다.



2. Anroid Project에 오픈소스 프로젝트 추가하기.


이제때까지의 포스팅에서는 clone을 통한 소스파일을 다운 받고, res소스 파일 및 소스 파일들을 복사 붙여넣기를 통해서 오픈소스를 프로젝트에 추가하였었는데요. 이건 저의 심각한 착각으로 일어난 일이었습니다. ㅜㅜ 


이클립스와 GitHub 연동을 하여야만 Android 프로젝트에 오픈 소스를 추가 할 수 있는줄 알아서 덜컥 겁부터 먹고서는 프로젝트에 추가하지 못하였었는데요, 알고보니 Android 프로젝트에 오픈소스를 단순히 사용만 할 경우에는 이클립스 + GitHub 연동이 전혀 필요가 없더군요.

다만 사용방법이 오픈소스마다 다른 것이었습니다. 


그리고  오픈소스마다 해당 사용법을 친절히 안내하고있는 상태구요. android-view-flow 오픈 소스 같은 경우엔 아래와 같이 설명이 나와있는데.



View Flow for Android

ViewFlow is an Android UI widget providing a horizontally scrollable ViewGroup with items populated from an Adapter. Scroll down to the bottom of the page for a screen shot.

The component is a Library Project. This means that there's no need to copy-paste resources into your own project, simply add the viewflow component as a reference to any project.


내용을 요약하여 보자면, "이 오픈소스 프로젝트는 Library Project이다. 리소스 파일들을 너의 프로젝트에 복사 붙여넣기 할 필요 없다." 정도가 되겠네요. 그렇습니다. 복사 붙여넣기는 뻘짓이된거죠. (예외적으로 복사 붙여넣기 해야하는 프로젝트도 있습니다.)


그리하여 새로운 프로젝트를 하나 만들고 해당 프로젝트에 android-view-flow 오픈소스를 추가하여 보도록 하겠습니다. 



(1) 프로젝트 생성




프로젝트 이름은 LibraryProject 로 설정하였구요. 그외에는 별다른 특이 사항이 없어서 그저 Next 버튼 연타 ㅎㅎ



(2) android-view-flow 프로젝트 소스 import (해당 소스 파일 다운 받는건 "Android UI를 만들어 보자 [3] - Tabbar 만들기 - "을 참고 하세요)






(2) LibraryProject에 viewflow 프로젝트 추가하기









(3) 최종결과





위 결과와 같이 프로젝트의 속성에서 Library 프로젝트를 추가하여 매우 간단하게 자기의 프로젝트에 추가 할 수 있습니다. gen 폴더에 res 관련된 데이터도 다 들어감은 물론, 소스들 까지 한꺼번에 추가하게 되는것이죠;


이러한 결과 이제껏 저의 포스팅은 절반이 쓸모없는 포스팅이 되었을뿐만 아니라 괜히 멍청한 포스팅 때문에 손발이 고생하셨을 분들에게 죄송할 따름이네요 ㅜㅜ 


다음 포스팅 부터는 확실하게 알아보고 포스팅을 하도록 유의하겠습니다~!!! 





posted by 엡뽀
2012. 12. 31. 17:20 Programing/Android


드디어 Android UI 만들어 보자의 마지막 포스팅이네요...;; 개인적으로 시간이 잘 안난것도 이유가 되겠지만 더 큰 이유는 귀찮니즘 때문에 너무 질질 끌어왔었네요;; (이 Androud UI 만들기 포스팅만 몇주를 하고있는 것같은;;;)


다시 한번 마음을 다잡으며 포스팅을 열심히 해볼렵니다. 아자아자!! ㅎㅎ



다시 본론으로 넘어와서, 이전 포스팅까지의 내용을 정리하여 보면, Activity를 두개 만들어서, 하나에선 기본 뷰들만 나타나고, 다른 하나에서는 리스트 뷰가 나타나도록 구성한뒤, 기본 뷰에서 Action bar를 통하여 리스트 뷰의 엑티비티가 실행되도록 프로젝트를 작성하였습니다. 


여기에 Tabbar를 추가하여 두개의 엑티비티로 되어있는 프로젝트를 하나의 엑티비티에서 두개의 뷰로 볼수있는 구조로 변경하도록 하겠습니다.  단 이 Tabbar도 오픈소스를 적용하여 진행하도록 하겠습니다. ( 처음 계획은 오픈 소스는 살며시 스쳐 지나가겠금 할려했었는데 자꾸만 오픈소스를 추가 하게 되네요;; github 도 쓸줄도 모르면서 ㅜㅜ)




▶android-viewflow 오픈소스

URL : https://github.com/pakerfeldt/android-viewflow

 




벌써 3번째 오픈 소스 사용이니 파일 복사 부분은 간략히만 짚고 넘어가겠습니다.




res\values\attrs.xml 내용 복사

    <declare-styleable name="ViewFlow">
        <attr name="sidebuffer" format="integer" />
    </declare-styleable>
    <declare-styleable name="CircleFlowIndicator">
        <attr name="activeColor" format="color" />
        <attr name="inactiveColor" format="color" />
        <attr name="radius" format="dimension" />
		<attr name="centered" format="boolean" />
		<attr name="fadeOut" format="integer" />
		<attr name="inactiveType">
			<flag name="stroke" value="0" />
			<flag name="fill" value="1" />
		</attr>
		<attr name="activeType">
			<flag name="stroke" value="0" />
			<flag name="fill" value="1" />
		</attr>
    </declare-styleable>    
    <declare-styleable name="TitleFlowIndicator">
        <attr name="titlePadding" format="dimension" />
        <!-- Left/right padding of not active view titles. -->
        <attr name="clipPadding" format="dimension" />
        <attr name="selectedColor" format="color" />
        <attr name="selectedBold" format="boolean" />
        <attr name="selectedSize" format="dimension" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="footerLineHeight" format="dimension" />
        <attr name="footerColor" format="color" />
        <attr name="footerTriangleHeight" format="dimension" />
        <attr name="customTypeface" format="string" />
    </declare-styleable>


프로젝트에 org.taptwo.android.widget 패키지 추가


src\org\taptwo\android\widget\ 파일들 전체 복사


p.s) 소스파일들을 추가 하시게 되면, 소스에 오류가 나타납니다. 패키지 명이 달라서 나타나는 증상이니, 

import org.taptwo.android.widget.viewflow.R; 이분을 제거 하고 다시 패키지명.R을 임포트 하시면 됩니다. (간단하게 이클립스에서 Ctrl + Shift + O 한번  하시면 됩니다.)




그럼 이것으로 오픈 소스를 사용할 준비는 완료되었으니, 기존의 소스들을 수정 하도록 하겠습니다.


1. activity_main.xml 파일 수정


- activity_main.xml -

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/blog.example.androidui"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <com.markupartist.android.widget.ActionBar
        android:id="@+id/actionbar"
        style="@style/ActionBar" />

    
    <org.taptwo.android.widget.ViewFlow
        android:id="@+id/viewflow"
		android:duplicateParentState="true" 
		android:layout_width="fill_parent" 
		android:layout_height="0dip"
		android:layout_weight="1">
	    
	</org.taptwo.android.widget.ViewFlow>
     <View
        android:layout_width="fill_parent"
        android:layout_height="2dip"
        android:background="#FFFF0000"
        />
    <LinearLayout android:layout_width="fill_parent"
		android:gravity="center_horizontal" android:id="@+id/header_layout"
		android:orientation="vertical" 
		android:layout_height="wrap_content">
		
        <org.taptwo.android.widget.TitleFlowIndicator
			android:id="@+id/viewflowindic" 
			android:layout_height="48dip"
			android:layout_width="fill_parent"
			app:footerLineHeight="2dp"
			app:footerTriangleHeight="10dp" 
			app:textColor="#A0FF0000" 
			app:selectedColor="#FFFF0000" 
			app:footerColor="#FFFF0000" 
			app:titlePadding="10dp" 
			app:textSize="17dp" app:selectedSize="18dp" 
			android:layout_marginTop="10dip" 
			app:clipPadding="5dp">
		</org.taptwo.android.widget.TitleFlowIndicator>

	</LinearLayout>

</LinearLayout>


우선 Action Bar 아래에 나오던 기본 뷰들을 전부 지웠구요, 그 부분에 viewflow 와 TitleFlowIndicator가 나타나도록 수정하였고, 뷰들의 속성 값들을 수정하였습니다.

 

자 그런데 여기서 TitleFlowIndicator 속성을 보시게되면 app: 이라는 접두어가 붙은 속성들이 등장하게됩니다. 

이 android-viewflow 오픈 소스는 app 이라는 xml 네임스페이스를 추가하여 view들의 속성을 지정하고있는데요. 이에 따라 android-viewflow 의 객체를 포함하는 최상위 view는 (여기선 LinearLayout 가 되겠지요.)  'xmlns' 라는 속성값을 통해 app 이라는 네임스페이스를 아래와 같이 추가 해주어야 합니다. 


xmls:app = "http://schemas.android.com/apk/res/프로젝트 패키지명"


p.s) 그런데 네임스페이스라고 보는게 옳은건지 잘모르겠네요;; 그저 이해를 돕기 위해 쓴 말이라고 생각하시면 될 것같습니다. 




2. default.xml 파일 추가


-default.xml-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_marginLeft="16dip"
        android:layout_marginRight="16dip"
        android:layout_marginTop="30dip"
        android:layout_weight="1"
        android:orientation="vertical" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dip"
            android:text="@string/session"
            android:textColor="#000000"
            android:textSize="22sp" />

        <View
            android:layout_width="fill_parent"
            android:layout_height="1dip"
            android:background="#000000" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="48dip"
            android:baselineAligned="true" >

            <EditText
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_marginBottom="4dip"
                android:layout_marginRight="4dip"
                android:layout_marginTop="4dip"
                android:layout_weight="1"
                android:hint="@string/hint" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="8dip"
                android:contentDescription="@string/modify"
                android:src="@drawable/content_edit" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="48dip" >

            <EditText
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="4dip"
                android:layout_marginRight="4dip"
                android:layout_marginTop="4dip"
                android:hint="@string/hint" />
        </LinearLayout>

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dip"
            android:text="@string/session"
            android:textColor="#000000"
            android:textSize="22sp" />

        <View
            android:layout_width="fill_parent"
            android:layout_height="1dip"
            android:background="#000000" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="48dip"
            android:baselineAligned="true" >

            <Spinner
                android:id="@+id/androidui_sp_1"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_marginBottom="4dip"
                android:layout_marginRight="4dip"
                android:layout_marginTop="4dip"
                android:layout_weight="1" />

            <Spinner
                android:id="@+id/androidui_sp_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="4dip"
                android:layout_marginLeft="4dip"
                android:layout_marginTop="4dip" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="48dip"
            android:baselineAligned="true" >

            <EditText
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_marginBottom="4dip"
                android:layout_marginRight="4dip"
                android:layout_marginTop="4dip"
                android:layout_weight="1"
                android:hint="@string/hint" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="4dip"
                android:layout_marginLeft="4dip"
                android:layout_marginTop="4dip"
                android:text="@string/send" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


별거 없습니다. 그냥 기존 activity_main.xml 에있던 기존 뷰들로 새로운 xml 파일을 하나 더 만들었습니다. 



3. activity_list.xml 파일 수정

- activity_list.xml -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <com.markupartist.android.widget.PullToRefreshListView
        android:id="@+id/android:list"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:cacheColorHint ="#00000000"
        />
	
</LinearLayout>


이것도 별거 없습니다. 기존 소스에선 ActionBar와 Textview로 만들어진 네이게이션바를 빼고, 속성을 몇가지 수정한게 전부입니다. 



4. ViewFlowAdapter 구현


viewflow 클래스는 listview 처럼 Adapter를 통하여 데이터 및 뷰를 보여주고있습니다. 이러한 이유때문에 activity_main.xml 파일 외에 두개의 xml 파일이 추가적으로 필요하여, default.xml 파일을 새로 만들고, activity_list.xml 파일을 수정하였습니다. 



또한 TitleFlowIndicator 클래스는 TitleProvider 인터페이스를 구현한 클래스로 부터 데이터를 읽어들이는데 ViewFlowAdapter 클래스가 TitleProvider 인터페이스까지 구현하도록 하겠습니다.


- ViewFlowAdapter.java -

package blog.example.androidui;

import org.taptwo.android.widget.TitleProvider;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class ViewFlowAdapter extends BaseAdapter implements TitleProvider {

	private LayoutInflater mInflater;
	
	private String[] titles = {"View1", "View2"};    //타이틀
	
	public ViewFlowAdapter(Context context){
		mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
	
	
	@Override
	public int getCount() {
		return titles.length;    //아이템 갯수.
	}

	@Override
	public Object getItem(int position) {
		return position;
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

         /* 포지션에 따라 생성하는 view를 다르게 설정 */
 
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if(convertView == null){
			if(position == 0){	//기본뷰
				convertView = mInflater.inflate(R.layout.default_view, null);
				
			}else{	//리스트뷰
				convertView = mInflater.inflate(R.layout.activity_list, null);
			}
		}
		
		return convertView;
	}

	@Override
	public String getTitle(int position) {    //타이틀 값.
		return titles[position];
	}

}


ViewflowAdapter 클래스는 BaseAdapter를 상속받아 만든 클래스이기 때문에 특별히 따로 설명드릴만한건 없는것 같습니다. 

다만 getView 메소드에서 포지션값에 따라 view가 다르게 생성되는 부분만 유의 하시면 될것같습니다. 



4. MainActivity 수정


- MainActivity.java -

package blog.example.androidui;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Vector;

import org.taptwo.android.widget.TitleFlowIndicator;
import org.taptwo.android.widget.ViewFlow;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

import com.markupartist.android.widget.ActionBar;
import com.markupartist.android.widget.ActionBar.Action;
import com.markupartist.android.widget.ActionBar.IntentAction;
import com.markupartist.android.widget.PullToRefreshListView;
import com.markupartist.android.widget.PullToRefreshListView.OnRefreshListener;

public class MainActivity extends Activity {

	private ViewFlow viewFlow;  //오픈 소스 객체.

	
	//listview 관련
	private PullToRefreshListView list = null;
	
	private String[] mStrings = {
            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
            "Allgauer Emmentaler"};
	private LinkedList<String> mListItems;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
        actionBar.setTitle("Home");
        
        final Action shareAction = new IntentAction(this, createShareIntent(), R.drawable.ic_title_share_default);
        actionBar.addAction(shareAction);
        
        //ListActivity를 실행하는 Action 주석 처리.
        //Intent intent = new Intent(this, ListViewActivity.class);
        //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        
        //final Action otherAction = new IntentAction(this, intent, R.drawable.ic_title_export_default);
        //actionBar.addAction(otherAction);  
        
        
        viewFlow = (ViewFlow) findViewById(R.id.viewflow);
        ViewFlowAdapter adapter = new ViewFlowAdapter(this); //adapter 객체 생성
        viewFlow.setAdapter(adapter); //adapter 설정
        
        TitleFlowIndicator indicator = (TitleFlowIndicator) findViewById(R.id.viewflowindic);
		indicator.setTitleProvider(adapter); // title provider 설정
		viewFlow.setFlowIndicator(indicator); //viewflow 객체에 titleflowindicator 설정.
        
	// 기존  MainActivity 소스  	
        Spinner sp1 = (Spinner)viewFlow.findViewById(R.id.androidui_sp_1);
        Spinner sp2 = (Spinner)viewFlow.findViewById(R.id.androidui_sp_2);
        
        Vector<String> data1 = new Vector<String>();
        Vector<String> data2 = new Vector<String>();
        
        data1.add("2011-12-25");
        data2.add("8:00 am");
        
        ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(
				this,
				android.R.layout.simple_spinner_item,
				data1);

        adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		sp1.setAdapter(adapter1);
		
		ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(
				this,
				android.R.layout.simple_spinner_item,
				data2);

		adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		sp2.setAdapter(adapter2);
        
		
		// 기존 ListActivity 소스 
		list = (PullToRefreshListView)viewFlow.findViewById(android.R.id.list); //  list의 id값이 android의 list 값이기 때문에 androi.R 을 참조.
		
		mListItems = new LinkedList<String>();
        mListItems.addAll(Arrays.asList(mStrings));
        
        ArrayAdapter<String> listadapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mListItems);

        list.setAdapter(listadapter);
		
		
		list.setOnRefreshListener(new OnRefreshListener() {
            public void onRefresh() {
                // Do work to refresh the list here.
                new GetDataTask().execute();
            }
        });
    }

	private class GetDataTask extends AsyncTask<Void, Void, String[]> {

        protected String[] doInBackground(Void... params) {
            // Simulates a background job.
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                ;
            }
            return mStrings;
        }

        protected void onPostExecute(String[] result) {
            mListItems.addFirst("Added after refresh...");

            // Call onRefreshComplete when the list has been refreshed.
            if(list != null) list.onRefreshComplete();

            super.onPostExecute(result);
        }
    }
	
	
	/* If your min SDK version is < 8 you need to trigger the onConfigurationChanged in ViewFlow manually, like this */
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		if(viewFlow != null) viewFlow.onConfigurationChanged(newConfig);	//Activity 환경설정 변경 
		super.onConfigurationChanged(newConfig);
	}
	
    public static Intent createIntent(Context context) {
        Intent i = new Intent(context, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        return i;
    }
    
    private Intent createShareIntent() {
        final Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_TEXT, "Shared from the ActionBar widget.");
        return Intent.createChooser(intent, "Share");
    }
}


실행 결과















기본 뷰에서 보내기 버튼 옆에있는 EditText를 선택하면 키보드가 올라오면서 선택된 EditText가 보이지 않는 버그가 있긴하지만 최종 목표를 달성하였기 때문에 쿨하게 무시하도록 하겠습니다. (나란 남자 이런남자)


여기까지 Android UI 만들기 포스팅이었구요, 무한 테클 및 질문 환영합니다. 감사합니다. 



AndroidUI - 최종.zip






posted by 엡뽀
2012. 12. 20. 13:17 Programing/Android

2. 리스트 View

이번엔 리스트 View를 만들어 볼껀데요. 별다른거 없이. STATE BAR, ACTION BAR, LISTVIEW, NAVIGATION BAR로 화면 구성을 하도록 하겠습니다. 


- ListViewActivity -


최종 프로젝트의 목적은 하나의 Activity 에 두개의 View를 만들어서 네비게이션 바를 통해 화면 전환이 일어나도록 하는 것이지만, 우선은 새로운 Activity를 만들어서 MainActivity에서 ACTION BAR -> ORDER ACTION 버튼으로 화면 전환이 일어나도록 하겠습니다. 반대로 ListActivity 에서는 홈버튼을 누르면 MainActivity로 되돌아가는(하지만 사실상 ActivityStack에 의하여 back키 한번만 눌러도 되죠 ㅎㅎ)식으로 구성하겠습니다. 


또한 기본 ListView를 그대로 사용하는 것보다 오픈소스를 이용하여 아래로 스크롤시 아이템이 추가 되는 리스트를 사용하여 화면 구성을 하도록 하겠습니다. 


▶ android-pulltorefresh 오픈소스.

 URL : https://github.com/johannilsson/android-pulltorefresh

(또 다시 오픈 소스를 프로젝트에 추가를 해야하는군요... 그렇습니다, 또 다시 복사 붙여넣기!!!)



파일 다운로드 및 압축 풀기.




다운로드를 풀게 되면, pulltorefresh폴더와 pulltorefreshexample 폴더가 나오게 되는데 이중 pulltorefresh 폴더 내용물들을 복사하여 프로젝트에 붙여넣기 하시면 됩니다. 



res\drawable



res\drawable-hdpi (전체 붙여넣기)



res\drawable-ldpi (전체 붙여넣기)



res\drawable-mdpi (전체 붙여넣기)



res\layout (전체 붙여넣기)



res\values

strings.xml 파일은 프로젝트에 존재하니깐 이번에도 내용 복사로 하겠습니다.



res\values\strings.xml

    <string name="pull_to_refresh_pull_label">Pull to refresh...</string>
    <string name="pull_to_refresh_release_label">Release to refresh...</string>
    <string name="pull_to_refresh_refreshing_label">Loading...</string>
    <string name="pull_to_refresh_tap_label">Tap to refresh...</string>



src\com\markupartist\android\widget 

(소스 파일은 기존에 추가 하였던 com.markupartist.android.widget 패키지에 넣으시면 됩니다.)


이것으로 android-pulltorefresh 오픈 소스를 사용할 준비가 다 되었구요. 새로운 Activity와 레이아웃 파일을 만들어 보도록 하겠습니다. 


- activity_list.xml -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.markupartist.android.widget.ActionBar
        android:id="@+id/actionbar"
        style="@style/ActionBar" />

    <com.markupartist.android.widget.PullToRefreshListView
        android:id="@+id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="48dip"
        android:background="#a0ff0000"
        android:gravity="center"
        android:text="@string/navigation"
        android:textColor="#000000"
        android:textSize="22sp" />

</LinearLayout>

레이아웃 파일에서 리니어레이아웃을 최상위로 잡고, actionbar, listview, textview를 추가하였습니다.
여기서 하나 짚고 넘어가야하는 부분이, com.markupartist.android.widget.PullToRefreshListView 뷰의 id 설정 부분을 보시면 

android:id = "@+id/android:list" 

로 되어있는데요. 이는 activity를 만들때 ListActivity 클래스를 상속받아 만들기 위해서 지켜야하는 약속(?) 같은 것입니다. ListActivity 클래스는 Listview를 꼭 포함해야하며, Listview의 id가 android:list 값을 가져야합니다. (Android Developers 참조

하지만 사실상 Activity로 만든 다음에 findViewByID 메소드를 이용해서 list 객체를 얻어와도 상관없지만, 오픈소스의 예제를 충실히 따르기 위해서 id값을 저렇게 설정 하도록 하겠습니다. 



- ListViewActivity.java -

public class ListViewActivity extends ListActivity {
	//리스트 아이템.
	private String[] mStrings = {
            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam",
            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
            "Allgauer Emmentaler"};
	private LinkedList<String> mListItems;    //adapter 데이터 객체.
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_list);
		
                 //action bar 객체 얻기. 
		final ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
        actionBar.setTitle("ListView");  //action bar 타이틀 설정.
        
        //action bar에 홈 action 설정. 
        actionBar.setHomeAction(new IntentAction(this, MainActivity.createIntent(this), R.drawable.ic_title_home_default));
        actionBar.setDisplayHomeAsUpEnabled(true); //action bar에 홈 버튼 보이기
        
         //OnRefreshListener 리스너 설정.
        ((PullToRefreshListView) getListView()).setOnRefreshListener(new OnRefreshListener() {
            public void onRefresh() {
                // Do work to refresh the list here.
                new GetDataTask().execute(); //Task 실행.
            }
        });
        
        mListItems = new LinkedList<String>(); //adapter 데이터 객체 생성
        mListItems.addAll(Arrays.asList(mStrings)); //데이터 설정
        
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mListItems); //adapter 생성. 

        setListAdapter(adapter); //리스트에 어뎁터 설정.
        
	}
	
	//데이터 추가 Task
	private class GetDataTask extends AsyncTask<Void, Void, String[]> {

        protected String[] doInBackground(Void... params) {
            // Simulates a background job.
            try {
                Thread.sleep(2000); //2초동안 프로세스 중지.
            } catch (InterruptedException e) {
                ;
            }
            return mStrings; //onPostExecute 함수에 넘겨줄 데이터 리턴.
        }

        protected void onPostExecute(String[] result) {
            mListItems.addFirst("Added after refresh..."); //"Added after refresh..." 데이터 추가
            // Call onRefreshComplete when the list has been refreshed.
            ((PullToRefreshListView) getListView()).onRefreshComplete(); //변경 완료.

            super.onPostExecute(result);
        }
    }

}



ListViewActivity 코드에선 두가지 정도만 짚고 넘어가면 될 것 같습니다. 홈 action과 listview. 


1. action bar의 홈 action 

홈 action을 설정하는 코드를 보게 되면, 

actionBar.setHomeAction(new IntentAction(this, MainActivity.createIntent(this), R.drawable.ic_title_home_default));

로 되어있는데요. IntentAction 이라는 객체는 Context, intent, int를 매개변수로 받는 생성자를 가지고있습니다. 여기서 intent를 넘겨줄때 MainActivity의 static 메소드를 호출하여, 인텐트를 넘겨주고있습니다.

- MainActivity.java -

    public static Intent createIntent(Context context) {
        Intent i = new Intent(context, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        return i;
    }


자 그럼 여기서, 홈 acion, 즉 홈키를 누르면 뒤로 가야하는데, 왜 인텐트를 생성해서 넘겨주느냐? 하는 문제점이있는데요. 여기에서 제가 짚고 넘어가고 싶었던 인텐트의  속성(?)이 키워드입니다.

만약 소스코드에서 intent에 addFilags 를 하지않았다고 가정하게되면, ActivityStack이 아래와 같이 될것입니다. 

(출처 : 휴휴휴님 블로그)

즉, 뒤로 가기와 같은 효과가 아니라 새로운 Activity가 하나더 생성되게 되는거죠. 이러한 문제점을 intent의 flag로 해결할 수 있습니다. 


아래는 intent에 FLAG_ACTIVITY_CLEAR_TOP이라는 FLAG를 사용한 ActivityStack입니다. 



FLAG_ACTIVITY_CLEAR_TOP 플레그는 실행하고자 하는 Acitivity가 존재할 경우, 해당 Activity 위에있는 모든 activity를 종료시켜 줍니다. 따라서 홈으로 돌아가는 듯한 효과를 받게 되는 거죠. 이 FLAG 외에도 여러가지 FLAG가 존재 하는데요. 휴휴휴님의 블로그에서 자세히 소개 되고있습니다. (안드로이드 알아두면 요긴한 FLAG_ACTIVITY 네가지 :: http://huewu.blog.me/110087045138?Redirect=Log&from=postView )


2. android-pulltorefresh

오픈소스의 listview  "setOnRefreshListener"라는 메소드를 통해서 유저가 새로고침을 하게 될 경우 해야할 작업을 실행 할 수 있도록 해줍니다. 하지만 여기서 OnRefreshListener 리스너는 실행완료까지 자동으로 해주는 것은 아닙니다. 실제 작업이 완료된 이후에. listview의 onRefreshComplete() 메소드를 호출해주어야하죠.

이 소스코드에선 setOnRefreshListener 메소드를 통해 GetDataTask 를 실행하는 OnRefreshListener 를 구현한 임시 객체를 넘겨주고, 사용자가 새로고침(스크롤이 맨위로 올라가있는 상황에서 아래로 내렸을때) GetDataTask를 실행합니다.

GetDataTask 클래스는 AsyncTask 클래스를 상속받은 객체이며, doInBackground 메소드에선 하는 일없이, 2초간 쓰레드를 멈추후 작업을 종료합니다. 작업이 종료되면 onPostExecute 메소드가 호출되게 되는데 이때 adapter에서 사용하는 객체의 맨 처음 부분에 "Added after refresh..."라는 데이터만 추가한뒤에 listview의 onRefreshComplete() 메소드를 호출합니다.


여기까지가 두번째 Acitivity를 생성하여 호출하는 작업입니다. 마지막으로 Activity를 추가하였으니, 매니페스트 파일을 수정하여줍니다. 


- AndroidManifest.xml -

    <activity
            android:name=".ListViewActivity"
            android:label="@string/title_activity_list" >
    </activity>


(위 부분을 application 태그 안에다 추가 해주시면 됩니다. )


여기까지가, 기본뷰를 만들고, Activity를 추가하여 listview를 만드는 과정이었습니다. 여기까지 된 전체 소스를 올려드리도록 하겠으며, 다음 포스팅에선 두개의 Activity로 되어있는 구성을 하나의 Activity로 구성하면서, Tabbar로 두개의 화면을 보여줄수 있도록 수정하는 작업을 하도록 하겠습니다. 


현재 까지 작업된 전체 소스 파일.

AndroidUI.zip







posted by 엡뽀
2012. 12. 2. 00:58 낙서장

최근 Android 관련 몇가지를 포스팅 하기 시작하였는데.. 분명 누군가 들어오는 것 같다. 나 이외에 아직 들어올 만한 사람이 없는데 들어오고 있다. 확실하다. 


하지만 모든 글에 댓글 0,  방명록도 0


하하하하하하하하하하하하하하하 희뱀

'낙서장' 카테고리의 다른 글

블로그의 시작  (0) 2012.11.28
posted by 엡뽀
2012. 11. 29. 16:50 Programing/Android


1. 기본 View 만들기.

기본 View를 만들기 전에 Example 그림을 다시 한번 보면서 어떤 어떤 View들이 들어가있느지 부터 확인을 해 보겠습니다. 


Example


STATUS BAR, ACTION BAR, TextView, EditText, ImageView(혹은 ImageButton), Spinner, Button NAVIGATION BAR
구성이 되어있네요. 


여기서 STATUS BAR, ACTION BAR는 API 4.0이상으로 빌드 타겟으로 프로젝트를 생성한다면 다른 레이아웃 수정없이 자동적으로 구성이 됩니다. 하지만 여기서 짚고 넘어가야할게 사실상 4.0 이상 버젼보다 2.2(프로요)와 2.3(진져브레드) 가 더 많지요.


VersionCodenameAPI

Distri

1.5Cupcake30.1%
1.6Donut40.3%
2.1Eclair73.1%
2.2Froyo812%
2.3 - 2.3.2Gingerbread90.3%
2.3.3 - 2.3.71053.9%
3.1Honeycomb120.4%
3.2131.4%
4.0.3 - 4.0.4Ice Cream Sandwich1525.8%
4.1Jelly Bean162.7%







(출처 : http://developer.android.com/about/dashboards/index.html)


물론 앱의 빌드 타겟 대상은 개발자 마음대로라 하시고 싶으신 대로 하면됩니만, 제 개인적인 판단으로는 4.0이상으로 해서 현재 약 65%되는 사용자들을 놓치는 것보단 2.2로 빌드하여 많은 사용자들이 이용 할 수 있도록 하는 주의 입니다. 

그럼 여기서 ACTION BAR가 2.2에선 사용 할 수 없는 문제가 발생합니다. 그냥 텍스트 뷰를 ACTION BAR의 크기처럼 만들어도 상관은 없겠지만,  ACTION BAR를 하위 버젼에서도 사용할 수 있는 Open source가 있습니다.


* android-actionbar Open source

URL : https://github.com/johannilsson/android-actionbar



이렇듯 오픈 소스로 이클립스에서 git 연동하여 자신의 프로젝트에 해당 소스를 첨부하여 사용가능한듯 한듯 하나 제가 아직 사용할 줄 몰라서 ㅜㅜ (차후에 공부를 해서;; 이클립스와 git 연동 관련해서 포스팅을 하도록 하겠습니다.ㅜㅜ)


그리하여 제가 한 방법은 소스파일을 다운로드해서 그냥 프로젝트에다 붙여넣기!! ㅎㅎㅎㅎㅎ
우선 AndroidUI 라는 프로젝트를 생성한 후에 다운로드 한 소스파일을 붙여넣는거죠. (프로젝트 생성은 다들 아실꺼라 믿고 그냥 넘어가겠습니다. ㅎㅎ)


76 commits 라고 되어있는 윗부분에 보시면 Downloads 라는 부분이있습니다. 해당 페이지로 가시면 zip 파일 또는 tar.gz 파일로 다운을 받을 수가 있는데, zip 파일을 다운 받은 후 압축풀어서 res에있는 레이아웃 파일이든, 이미지 파일이든 혹은 소스 파일이든 전부 그냥 복사해서 제 프로젝트에다가 추가하겠습니다.





압축을 푸시면 actionbar 폴더와 actionbarexample 폴더가 나옵니다. actionbar 폴더가 오픈 소스라고 보시면 되고, actionbarexample 폴더가 해당 오픈소스로 만든 프로젝트라고 보시면 됩니다. 




actionbar 폴더안에는 res 폴더,src 폴더 및 매니페스트 파일과 몇가지 파일이 나오는데요, 제가 필요한건 소스파일과 res안에있는 파일들이니 다른건 신경쓰고 붙여넣기 해야할 파일들만 보여드릴께요. (해당 파일들을 프로젝트의 같은 이름의 폴더에 넣으시면 됩니다.)



res\drawable



res\drawable-hdip



res\layout


res\values (strings.xml, styles.xml 두 파일은 기본프로젝트에 포함되어있어서 파일 복사가 아니라 내용 복사로 하였습니다.)



string.xml

Failed to open intent...



style.xml








src\com\markupartist\android\widget (소스는 com.markupartist.android.widget 패키지를 새로 만드신 후에 붙여 넣기 하시면 됩니다.)



자 드디어 android-actionbar 소스를 사용할 준비다 다되었군요. (진짜 드디어;;) 그럼 이제 다시 프로젝트로 넘어와서 메인레이아웃 소스를 만들어보도록 하겠습니다.



    
    

    

        
        

        
            
        
		

            
            

            
            
        

        

            
            
        

        
        

        
        

        

            
            

            
            
        

        

            
            

            
        
    

    
        
    


(코드하이라이터가 왜 이렇게 나타나는지 모르겟네요;; 이클립스에 붙여넣기 하신담에 Ctrl + Shift + F :: 소스 정리 단축키 누르셔야할듯;;)

그럼 몇가지 부분만 짚고 넘어가도록 하겠습니다. 

(1) 우선 오픈소스의 커스텀 뷰입니다.



com.markupartist.android.widget.actionbar 라는 태그가 있는 이 태그는 현제 프로젝트의 특정 소스를 xml 파일에서 뷰로 만들어주는 커스텀 태그라고 보시면 됩니다. 해당 소스를 붙여넣기 할때 com.markupartist.android.widget라는 패키지를 만든후에 복사를 한다고 말씀을 드렸었는데요. 혹시나 다른 패키지의 이름으로 하신분이있다면 이부분을 변경해야하며, res\layout에 붙여넣은 xml파일 내용물에 들어가있는 패키지 명도 바꾸어 주어야 합니다. 


(2) view



Session이라는 글자밑에있는 밑줄을 어떻게 구현할까하다가 그냥 view에다가 배경화면으로 검은색을 준다음 view의 높이를 1dip만 줘서 라인처럼 보이게 구현하였습니다. (이 외에 방법론 Shape를 만들어서 추가하면 될것같은데 이것과 관련해선 다음에 기회 봐서 포스팅을 하도록 하겠습니다. :: 점점 일이 많아 지는 느낌이네요;; ㅎㅎ;;)


(3) Navigation Bar


    


Navigation Bar는 기본 View와 리스트 View 둘다 완성이 된 이후에 또 오픈 소스를 사용하여 구성을 할 예정이라 단순하게 TextView를 만들어서 배치하여보았습니다. 그 외적인 다른 뷰들은 단순한 마진 값들만 준거라 찬찬히 살펴보시면 될 것이라 믿고, 소스부분으로 넘어가도록 하겠습니다.


(4)MainActivity.java




public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);	
        
        //ActionBar 객체 얻기
        final ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
        actionBar.setTitle("Home"); //액션바에 타이틀 설정
        
        //공유 엑션 객체 생성
        final Action shareAction = new IntentAction(this, createShareIntent(), R.drawable.ic_title_share_default);
        actionBar.addAction(shareAction); //공유 엑션을 엑션바에 추가
        
        //새로운 엑션 추가
        //final Action otherAction = new IntentAction(this, new Intent(this, ListViewActivity.class), R.drawable.ic_title_export_default);
        //actionBar.addAction(otherAction);
        
        //Spinner 설정
        Spinner sp1 = (Spinner)findViewById(R.id.androidui_sp_1);
        Spinner sp2 = (Spinner)findViewById(R.id.androidui_sp_2);
        
        Vector data1 = new Vector();
        Vector data2 = new Vector();
        
        data1.add("2011-12-25");
        data2.add("8:00 am");
        
        ArrayAdapter adapter1 = new ArrayAdapter(
				this,
				android.R.layout.simple_spinner_item,
				data1);

        adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		sp1.setAdapter(adapter1);
		
		ArrayAdapter adapter2 = new ArrayAdapter(
				this,
				android.R.layout.simple_spinner_item,
				data2);

		adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		sp2.setAdapter(adapter2);
        
    }

    
    public static Intent createIntent(Context context) {
        Intent i = new Intent(context, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        return i;
    }
    
    
    //공유 엑션 인텐트 만드는 메소드
    private Intent createShareIntent() {
        final Intent intent = new Intent(Intent.ACTION_SEND);	//묵시적 인텐트 선언
        intent.setType("text/plain");	//인텐트 타입지정
        intent.putExtra(Intent.EXTRA_TEXT, "Shared from the ActionBar widget.");	//인텐트 데이터 설정 
        return Intent.createChooser(intent, "Share");	//인텐트 리턴
    }
}
소스도 뭐 그다지 어려운게 없습니다. 그냥 findviewById 로 action 객체를 얻어오고, 타이틀 설정 및 버튼을 추가하는겁니다. createIntent 메소드는 쫌 짚고 넘어가고 싶은데.... 이에 대해서는 차후 ListViewActivity 클래스를 다 만들고 난 이후에 설명을 하도록 하겠습니다. (어짜피 MainActivity에선 만들기만 했지 사용하는 곳이 없어서 대략 난감하네요 ㅎㅎ)


이렇게 하여 실행한 화면입니다.





프로젝트 전체 파일은 ListView까지 작성한 후에 올리도록 하겠습니다. (이미 다 만들어 놓고 압축시켜놔서 따로 분리하기가 귀찮....)

P.S 혹시나 main layout 부분에서 에러가 나시는 분들은 string.xml에 제가 추가했던 텍스트가 추가 되지 않아서 그런거 일수 있으니, 그냥 text = "섹션" 과 같은 방식으로 변경하신 후 실행 해보세요.


posted by 엡뽀
2012. 11. 29. 13:54 Programing/Android

안녕하세요. 블로거 엡뽀라고 합니다.


지난번엔 안드로이드 래퍼런스 싸이트에 올라와있는 디자인 가이드라인을 번역하여
포스팅을 하였었는데요. 하지만 이런 가이드라인 만으로는 너무 뜬구름 잡기가 되버릴 수 있겠죠.
그리하여 이번 포스팅은 실제 Android UI를 구성해보고 디자인을 직접해볼려 합니다.


자 그럼, UI를 새로 구성해야하는데, 이때 도움을 받을 수 있는 유용한 App을 소개 하고자 합니다. 그 이름 하여
Android UI Pattern App. 말 그대로 안드로이드 UI 패턴들을 소개 하고있는 앱입니다. 

   Andrid UI Pattern App

(구글 플레이 : https://play.google.com/store/apps/details?id=com.groidify.uipatterns 혹은 마켓 검색 창에 Anroid UI Pattern 이라고 검색하시면 나옵니다.)

이 이후 Android UI pattern App을 "패턴앱" 이라 호칭하겠습니다.


패턴앱에서 소개 되고있는 UI 종류도 다양한데, Anction Bar & DashBoard, View pager & Tabbar, ListView, Map, 등등
오늘 제가 해볼 View는 ViewPagaer로 2개의 탭을 만든후에, 하나의 탭에서는 ListView가 나타나고, 또다른 뷰에서는 기본 View들을 보여주는 탭을 구성 해 볼까 합니다.

P.S 패턴앱에서 소개 되고있는 UI들은 오픈 소스로 사용하는데 지장이 없다고 하더군요. (안드로이드 만쉐이)


패턴앱 메인 화면

android-viewflow

android-pulltorefresh



UI 구성은 2개의 뷰(리스트뷰와 기본View)와 탭컨트롤러가 되는데요. 기본 View를 다 만든 후에 리스트뷰를 만들고 다 만들어진 후에 탭을 구성하는 방식으로 하겠습니다. 또한 기본 View는 저번 포스팅을 복습하는 차원에서 Metrics and Grids 가이드라인에서 나온 예제를 만들도록 하겠습니다. 


Example 



하지만 이번에도 역시나 기본 view , 리스트 뷰 만들기와 ViewPagaer 만들기는 다음 포스팅에서 하도록 하겠습니다.





posted by 엡뽀
prev 1 2 next