반응형

안드로이드에서 Animation 을 구현하는 방법은 2가지 입니다.


1. Frame Animation : 여러장의 사진을 바꿔가며 애니메이션을 실행

2. Tween Animaion : 이미지의 위치, 크기, 각도, 투명도를 조절하며 애니메이션 실행


우선 첫번째로

특정 이미지 뷰(ImageView)에 보여지는 그림이 자동으로

변경돼서 애니메이션을 실행하는 Frame Animation을 만들어 보겠습니다.


'START'버튼을 누르면 Animation이 시작됩니다.


동작결과부터 보겠습니다.




위의 Pink 캐릭터가 점프 하는 애니메이션을 위해

여러장의 이미지가 필요합니다.



Pink_Jump.zip



첨부파일로 첨부했으니 다운받으셔서

본인 프로젝트의 drawable-hdpi 폴더에 추가하세요.

(다른 해상도에 넣어도 됩니다.)


프레임 애니메이션(Frame Animation)

만들기 위해 프로젝트의 res폴더

drawable 폴더를 하나 만들고

그 안에 여러장의 이미지를 리스트업 한 xml 파일을 만듭니다.


즉, 여러장의 그림을 보유하고 있는

Drawable(그림 관리 클래스) 리소스를 만든다고 보시면 됩니다.



먼저 이 작업부터 하죠.

혹시나 해서 res폴더>>drawable폴더 생성 과정부터 보여드립니다.

'drawable' 폴더 이름은 절대 틀리면 안됩니다.



  




이제 'drawable' 폴더안에 여러장의 이미지 하나 하나를

Frame으로 하여 변경시킬 수 있는

Animation-list 리소스 파일을 만듭니다.

파일 이름은 'pink_jump' 로 하겠습니다.


역시 그림으로 보겠습니다.


  



'Root element' 로 'animation-list'를 선택하셔야 합니다.(한번 클릭)


이렇게 만들어진

'pink_jump.xml' 파일 입니다.

특별한 설명없이도 Frame당 100ms(0.1초)씩 보여진다는 것을

아실 수 있을 겁니다.


 

 pink_jump.xml

<animation-list xmlns:android="http://schemas.android.com/apk/res/android">

    

    <item android:drawable="@drawable/pink_jump_001"

        android:duration="100"/>

    

    <item android:drawable="@drawable/pink_jump_002"

        android:duration="100"/>

    

    <item android:drawable="@drawable/pink_jump_003"

        android:duration="100"/>

    

    <item android:drawable="@drawable/pink_jump_004"

        android:duration="100"/>

    

    <item android:drawable="@drawable/pink_jump_005"

        android:duration="100"/>

    

    <item android:drawable="@drawable/pink_jump_006"

        android:duration="100"/>

    

    <item android:drawable="@drawable/pink_jump_007"

        android:duration="100"/>

    

    <item android:drawable="@drawable/pink_jump_008"

        android:duration="100"/>    


</animation-list>



이제 이 Drawable 리소스 파일

설정하는 ImageView가 있는

activity_main.xml 파일입니다.


간단하게 애니메이션을 시작하는 버튼(Button) 1개,

애니메이션을 보여줄 ImageView 1개 입니다.

 

 activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >

    

    <Button android:id="@+id/button"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="FrameAnimation START"

        android:onClick="mOnClick"/>


    <ImageView 

        android:id="@+id/img"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerInParent="true"        

        android:src="@drawable/pink_jump"/>


</RelativeLayout>


ImageView의 src 로 위에서 만든 pink_jump.xml 파일이 적용되었다는 것이

중요합니다.



이제 Frame Animation이 가능한 상태는 되었습니다.

하지만 실행시켜도 애니메이션을 실행되지 않습니다.

src로 지정된 Drawable 리소스 파일인

pink_jump.xml 파일의 아이템들은

시작부터 자동으로 애니메이션이 되지는 않습니다.


그럼 이 여러장의 그림을 가지고 있는

Drawable 리소스에게 Frame 애니메이션이 실행되되록

소스코드를 만들어 보겠습니다.


주요 설명은 주석을 참고하시기 바랍니다.

'START' 버튼을 누를 때 마다

pink 캐릭터가 Jump 합니다.


 

 MainActivity.java

public class MainActivity extends Activity {

ImageView img;

//FrameAnimation에 의해 Animation을 실행할

//Animation Drawable 객체 참조변수

//즉, Frame 단위로 이미지를 바꿔서 그려주는 Drawable 객체

AnimationDrawable ani;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//ImageView 객체 참조

img=(ImageView)findViewById(R.id.img);

//ImageView에 src 속성으로 설정된 이미지를 Drawable 객체로 얻어오기. 

//Frame Aniamtion은 Drawable의 일종이므로 형변환 가능

ani=(AnimationDrawable)img.getDrawable();

//Frame Animation을 한번반 실행

//이 코드를 지우면 자동으로 반복함(기본값)

ani.setOneShot(true);

}

//onClick 속성이 지정된 View가 클릭되었을 때 자동으로 호출되는 콜백메소드

public void mOnClick(View v){

switch(v.getId()){

case R.id.button:

//'START' 버튼을 눌렀을 때 이전 Frame Animation이 진행중이면 정지

//Frame Animation은 한번 start()해주면 계속 Running 상태임.

//Frame Animation을 OneShot으로 하고 다시 시작하게 하고 싶다면

//이전 Frame Animation을 'stop'시켜야 함.

if(ani.isRunning()) ani.stop();

//AnimationDrawable 객체에게

//Frame 변경을 시작하도록 함.

ani.start();

break;

}

}

}

 

여기까지 Frame Animation의 기본적인 실행을 보았습니다.


이미지만 많다면 좀더 부드럽게 애니메이션이 진행되겠죠.


다음 포스트에서는 하나의 이미지뷰

여러 종류의 Frame Animation이 실행되도록 하겠습니다.


pink 캐릭터 jump도 하고 run도 하고 attack도 하도록 해보겠습니다.

반응형
반응형


이전 포스트의 ListView 예제들은

Data로 단순한 String 문자열을 사용했습니다.


하지만 실제 어플을 개발할 때 사용하는 ListView는

나열할 항목의 Data가 String 하나로 단순하지 않은 경우가 많죠.


그래서 이전 예제에서 사용했던

ArrayAdapter를 사용하기에는 다소 부족합니다.


그래서 실제로는 AdapterView의 일종인 ListView의 항목으로

보여줄 Data들을 적절한 View로 만들어주는

Adapter 객체를 사용자정의(Customize)해야 하는 경우가 많습니다.


이번 예제는 이를 위한 예제로서

대량의 데이터로 사용할 Data를 문자열2개와 이미지 하나로 할 겁니다.


실행결과를 먼저 보시는 것이 이해가 빠르겠네요.


예제는 요즘 유명한 비정상 회담 멤버들의 국적을

표시하는 예제입니다.


간단한 ListView이지만

각 항목마다 문자열2개, 이미지 하나를 보여줍니다.



실행화면


스크롤 되는 ListView

  

각 항목마다 이름, 국적, 국기 이미지를 표시합니다.


딱 봐도 어떤 구조인지 느껴지시죠??




이제 예제 소스를 소개하겠습니다.


먼저 프로젝트를 만들어

기본 Activity에서 보여줄 xml파일을 설계합니다.


activity_main.xml 레이아웃 파일

단순히 ListView 하나와 제목 TextView 하나입니다.

 

 activity_main.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:padding="5dp">

    

    <TextView 

        android:layout_width="match_parent"

        android:layout_height="30dp"

        android:text="비정상회담 멤버"

        android:textStyle="bold"

        android:gravity="center"

        android:background="#dddddd"/>


    <ListView 

        android:id="@+id/listview"

        android:layout_width="match_parent"

        android:layout_height="300dp"

        android:layout_marginTop="5dp"/>


</LinearLayout>

  


Java 소스파일은 잠시뒤에 소개하고

먼저 ListView의 한 항목으로 사용할 데이터인

이름, 국적, 국기 이미지 리소스는 하나의 멤버에 대한 정보인 만큼

하나의 클래스 객체로 관리하는 것이 용이하므로

이 3개의 값(이름,국적,이미지 리소스 아이디)을 멤버변수로 보관하는

데이터 클래스를 만들어 보겠습니다.



비정상회담 국기.zip


그전에 국기 이미지는 첨부파일에서 받아 다운받셔서

압축을 풀고

이 프로젝트의 res폴더>>drawable폴더 중 타겟 해상도의 폴더에 넣으세요.

저는 drawable-hdpi에 넣었습니다.

(제 에뮬레이터geny-motion이 hdpi 이기 때문에..)



이미지를 모두 넣었다면


이제 비정상 회담 멤버 한명 한명의 이름, 국적, 국기이미지를 저장할

데이터 클래스를 만들어 보겠습니다.


MainActivity.java 파일 안에 클래스를 선언하면

복잡해 보이기에 별도의 .java 소스 파일로 만듭니다.

코딩이 편하도록 같은 패키지안에 소스파일을 만듭니다.


이름, 국적을 저장하기 위한 String 2개,

국기 이미지 리소스 아이디를 저장하기위한 int형 변수 1개

(R.drawable.korea 같은 int형 ID 값)


 

 MemberData.java

//Member의 정보를 저장하기 위한 클래스.....

public class MemberData {

String name;    //이름 저장

String nation;   //국적 저장

int imgId;      //국기 이미지의 리소스 아이디

public MemberData(String name, String nation, int imgId) {

// TODO Auto-generated constructor stub

//생성자함수로 전달받은 Member의 정보를 멤버변수에 저장..

this.name= name;

this.nation=nation;

this.imgId=imgId;

}

//이 아래는 getter , setter 메소드듭입니다.

//OOP(객체 지향 프로그래밍)은 클래스 객체 외부에서 직접 엠머변수에 접근하는 것을 지양합니다.

//객체의 멤버변수 제어는 객체 스스로 하도록 해서 재사용성을 높인 방법이죠.

//getter, setter 멤버 메소드들은 그 목적으로 만들어 진 것이죠.

public void setName(String name) {

this.name = name;

}

public void setNation(String nation) {

this.nation = nation;

}

public void setImgId(int imgId) {

this.imgId = imgId;

}

public String getName() {

return name;

}

public String getNation() {

return nation;

}

public int getImgId() {

return imgId;

}


}


특별할 것 없는 데이터 클래스 입니다.



MainActivity.java 소스파일안에 이 데이터 객체들을 만드는 작업과

ListView 참조변수 작업만 먼저 수행하겠습니니다.

주석을 참고하시기 바랍니다.

 MainActivity.java

public class MainActivity extends Activity {

//이름,국적,이미지리소스아이디를 가지고 있는 MemberData 클래스의 객체를 

//배열로 보관하기 위한 ArrayList 객체 생성

//MemberData[] 이렇게 선언하는 일반배열은 배열 개수가 정해져 있어서 나중에 추가,삭제가 불편하죠.

//배열 요소의 개수를 유동적으로 조절할 수 있는 ArrayList 객체로 data 보관

ArrayList<MemberData> datas= new ArrayList<MemberData>();

//ListView 참조변수

ListView listview;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//이번 예제에서는 우선 직접 코딩으로 멤버정보를 입력하고

//다른 예제에서 추가/삭제 관련 작업을 해보겠습니다.

//비정상 회담(요즘 유명하기에 허락없이 도용합니다.-_-)멤버 정보 생성

datas.add( new MemberData("유세윤", "대한민국", R.drawable.korea));

datas.add( new MemberData("블레어", "호주", R.drawable.australia));

datas.add( new MemberData("기욤 패트리", "캐나다", R.drawable.canada));

datas.add( new MemberData("장위안", "중국", R.drawable.china));

datas.add( new MemberData("로빈", "프랑스", R.drawable.france));

datas.add( new MemberData("다니엘", "대한민국", R.drawable.germany));

datas.add( new MemberData("알베르토", "대한민국", R.drawable.italy));

datas.add( new MemberData("샘오취리", "대한민국", R.drawable.ghana));

//귀찮아서 다 못넣겠네요...-_-

//ListView 객체 찾아와서 참조

listview= (ListView)findViewById(R.id.listview);

}

}

 


이제 가장 중요한 작업입니다.


ListView는 AdapterView의 일종입니다.


즉, 대량의 데이터를 적절한 View 객체로 만들어주는

Adapter를 보유한 ViewGroup으로서 Adapter 객체가

만들어주는 View를 나열시켜주는 View Group입니다.


 이전 포스트들에서 소개한 ArrayAdapter는 단순하게

문자열을 나열할 때 손쉽게 사용했습니다.


하지만 지금 우리의 예제처럼

문자열 2개를 위아래로..

이미지 하나를 오른쪽에..

보여주도록 하는 View는 만들 수 없습니다.


그래서 이름, 국적, 국기이미지 아이디를 저장하고 있는

데이터를 가지고 앞에 보여드렸던

실행화면의 항목처럼 배치되도록 하는

View를 만들어내는 Adapter를 만들어야 겠습니다.

즉, 커스텀 Adapter(Custom Adapter)를 만들겠다는 겁니다.



먼저 커스텀 Adapter가 만들어낼 View(List의 항목하나)의

배치(레이아웃)을 설계하는 xml 레이아웃 파일을 만들겠습니다.



res폴더>>layout폴더>>list_row.xml 파일 생성

다들 알겠지만

노파심(?)에서 만드는 과정을 소개합니다.



  

 

마지막 사진이 우리가 만들 레이아웃 xml 파일의 Graphical Layout 입니다.

커스텀 Adapter가 만들어낼 View의 모양으로

ListView의 한 항목에 해당하는 모습니다.


xml파일입니다.

 list_row.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="70dp"

    android:orientation="horizontal"

    android:padding="3dp"

    android:background="#dddddd" 

    android:weightSum="10">

    

    <LinearLayout 

        android:layout_width="0dp"

        android:layout_height="match_parent"

        android:layout_weight="7"

        android:orientation="vertical"

        android:weightSum="5">

        

        <TextView android:id="@+id/text_name"

            android:layout_width="match_parent"

            android:layout_height="0dp"

            android:layout_weight="3"

            android:text="NAME"

            android:textSize="18sp"

            android:textStyle="bold"

            android:gravity="center_vertical"

            android:background="#ffffff"

            android:padding="3dp"/>

        

        <TextView android:id="@+id/text_nation"

            android:layout_width="match_parent"

            android:layout_height="0dp"

            android:layout_weight="2"

            android:text="NATION"

            android:gravity="center_vertical"

            android:layout_marginTop="2dp"

            android:background="#ffffff"

            android:padding="3dp"/>

        

    </LinearLayout>

    

    <ImageView android:id="@+id/img_flag"

        android:layout_width="0dp"

        android:layout_height="64dp"

        android:layout_weight="3"

        android:src="@drawable/korea"

        android:background="#ffffff"

        android:layout_marginLeft="3dp"/>    


</LinearLayout>

  

이제 Adapter가 만들어낼 View의 모양을 만들었으니

실제로 대량의 Data인

비정상 회담 멤버의 이름,국적,국기이미지 데이터들을 저장하고 있는

ArrayList인 'datas'

지금 만든 list_row.xml 의 모양으로 View 객체를

만들어내는 Adapter를 만들겠습니다.


MainActivity.java 파일이 너무 복잡하니

별도의 .java 소스파일로 커스텀 Adapter class를 설계하겠습니다.


여기서 가장 중요한 것은

우리가 만들려는 커스텀 Adapter class

'BaseAdapter'를 상속받아 만든다는 겁니다.

이 클래스가 기본적인 Adapter의 기능들을 수행하도록 되어 있습니다.

이 기본 기능들을 우리의 목적에 맞게

오버라이딩(overriding)해서 원하는 동작이 되도록 할 겁니다.


혹시나 해서 또 노파심(?)에

상속받아 클래스를 만드는 과정을 보겠습니다.


   


  

마지막 그림처럼 Class 소스파일이 만들어지면 성공입니다.


이제

비정상 회담 멤버들의 정보를 View 객체로 만들어주는

MemberDataAdapter 클래스 파일을 만들어 냅니다.

주석으로 설명을 많이 해놔서

코드가 엄청 길어 보이지만..

주석을 제외한 검정 글씨만 보면 많지 않습니다.


 

 MemberDataAdapter.java

//클래스의 이름은 다른 이름이어도 상관없지만 상속만 BaseAdapter를 잘 받으면 됩니다.

public class MemberDataAdapter extends BaseAdapter {

ArrayList<MemberData> datas;

LayoutInflater inflater;

public MemberDataAdapter(LayoutInflater inflater, ArrayList<MemberData> datas) {

// TODO Auto-generated constructor stub

//객체를 생성하면서 전달받은 datas(MemberData 객체배열)를 멤버변수로 전달

//아래의 다른 멤버 메소드에서 사용하기 위해서.멤버변수로 참조값 전달

this.datas= datas;

//list_row.xml 파일을 View 객체로 생성(inflating) 해주는 역할의 객체

//이 MemberDataAdapter 클래스를 객체로 만들어내는 클래스에서 LayoutInflater 객체 전달해주야 함.

//이번 예제어세는 MainActivity.java에서 전달.

//xml 종이의 글씨를 부풀려서 객체로 메모리에 만들어 낸다고 해서 '부풀리다(inflate)'라는 표현 사용

this.inflater= inflater;

}


//ListView에서 이 MemberDataAdapter 객체에게 요청하는 값으로서

//MemberDataAdapter 객체가 만들어낼 View의 개수를 리턴하는 메소드

//ListView에 나열되는 목록의 개수를 의미함.

//이 예제에서는 datas라는 ArrayList의 개수를 지칭함.

//특별한 경우가 아니라면 보통 datas의 size 를 리턴함.

@Override

public int getCount() {

// TODO Auto-generated method stub

return datas.size(); //datas의 개수를 리턴

}

//MemberDataAdapter의 특정 위치(position)에 해당하는 Data를 리턴하는 메소드

//이 예제에서는 datas의 특정위치에 해당하는  MemberData 객체를 리턴.

//ListView의 position은 가장 위에 목록부터(0,1,2,3...)으로 지정됨.

@Override

public Object getItem(int position) {

// TODO Auto-generated method stub

return datas.get(position);//datas의 특정 인덱스 위치 객체 리턴.

}

//특정 위치(position)의 data(MemberData)을 지칭하는 아이디를 리턴하는 메소드

//특별한 경우가 아니라면 보통은 data의 위치를 아이디로 사용하므로

//전달받은 position를 그대로 리턴함.

@Override

public long getItemId(int position) {

// TODO Auto-generated method stub

return position;

}

//이 커스텀 Adapter 클래스 설게에서 가장 중요한 메소드로서 

//ListView에서 한 항목의 View 모양과 값을 설정하는 메소드

//AdapterView의 일종인 ListView는 설정된 Adapter(이 예제에서는 MemberDataAdapter)에게

//대량의 데이터들(datas : MemberData객체 배열)을 보여주기에 적절한 View로 만들고 

//해당 데이터의 값으로 만들어 내는 핵심 메소드로서 ListView를 위에 만든 getCount()메소드의 리턴값만큼

//getView를 요구하여  목록에 나열함.

//즉, 이 메소드의 리턴값인 View 가 ListView의 한 항목을 의미합니다.

//우리는 이 리턴될 View의 모양을 res폴더>>layout폴더>>list_row.xml 파일을 만들어 설계합니다.

//첫번째 파라미터 position : ListView에 놓여질 목록의 위치.

//두번째 파라미터 convertview : 리턴될 View로서 List의 한 함목의 View 객체(자세한 건 아래에 소개)

//세번째 파라미터 parent : 이 Adapter 객체가 설정된 AdapterView객체(이 예제에서는 ListView)

@Override

public View getView(int position, View convertView, ViewGroup parent) {

// TODO Auto-generated method stub

//크게 getView의 안에서는 2가지 작업이 이루어 집니다.

//1. ListView의 목록 하나의 모양을 담당하는 View 객체를 만들어 내는 'New View'

//2. 만들어진 View에 해당 Data를 연결하는 'Bind View'

//1.New View

//지문의 한계상 자세히는 설명하기 어려우니 세부사항은 다른 포스트를 참고하시기 바랍니다.

//가장 먼저 new View를 하기 위해서 convertView 객체가 null인지 확인합니다.

//null을 확인하는 이유는 자원 재활용때문인데..

//짧게 설명하자면.. ListView에서 보여줄 목록이 만약 100개라면... 

//데이터의 양이 많아 분명 동시에 보여질 수 있는 목록의 개수를 정해져 있을 겁니다.

//그래서 이전 예제에서 보았듯이 ListView는 개수가 많으면 자동으로 Scroll되도록 되어 있지요.

//여기서 조금 생각해보시면 간단한데요.. 한번에 만약 5개 밖에 못보여진다면...

//굳이 나머지 95개의 View를 미리 만들 필요가 없겠죠.. 어차피 한번에 보여지는게 5~6개 수준이라면..

//그 정보의 View만 만들어서 안에 데이터만 바꾸면 메모리를 아낄 수 있다고 생각한 겁니다.

//여기 전달되어 체크되고 있는 converView 객체가 재활용할 View가 있으면 null이 아닌값을 가지고 

//있다고 보시면 되고 converView가 null이면 새로 만들어야 한다고 보시면 됩니다.

if( convertView==null){

//null이라면 재활용할 View가 없으므로 새로운 객체 생성

//View의 모양은 res폴더>>layout폴더>>list.xml 파일로 객체를 생성

//xml로 선언된 레이아웃(layout)파일을 객체로 부풀려주는 LayoutInflater 객체 활용.

convertView= inflater.inflate(R.layout.list_row, null);

}

//2. Bind View

//재활용을 하든 새로 만들었든 이제 converView는 View객체 상태임.

//이 convertView로부터 데이터를 입력할 위젯들 참조하기.

//이름을 표시하는 TextView, 국적을 표시하는 TextView, 국기이미지를 표시하는 ImageView

//convertView로 부터 findViewById()를 하시는 것에 주의하세요.

TextView text_name= (TextView)convertView.findViewById(R.id.text_name);

TextView text_nation= (TextView)convertView.findViewById(R.id.text_nation);

ImageView img_flag= (ImageView)convertView.findViewById(R.id.img_flag);

//현재 position( getView()메소드의 첫번재 파라미터 )번째의 Data를 위 해당 View들에 연결..

text_name.setText( datas.get(position).getName() );

text_nation.setText( datas.get(position).getNation() );

img_flag.setImageResource( datas.get(position).getImgId() );

//설정이 끝난 convertView객체 리턴(ListView에서 목록 하나.)

return convertView;

}


}



이제

MainActivity 소스파일에서 이 Adapter를 객체로 만들고

ListView에 설정하면 끝입니다.


완성된 MainActivity.java 소스파일입니다.

굵은 글씨가 새로 추가한 내용입니다.


 

 MainActivity.java

public class MainActivity extends Activity {

//이름,국적,이미지리소스아이디를 가지고 있는 MemberData 클래스의 객체를 

//배열로 보관하기 위한 ArrayList 객체 생성

//MemberData[] 이렇게 선언하는 일반배열은 배열 개수가 정해져 있어서 나중에 추가,삭제가 불편하죠.

//배열 요소의 개수를 유동적으로 조절할 수 있는 ArrayList 객체로 data 보관

ArrayList<MemberData> datas= new ArrayList<MemberData>();

//ListView 참조변수

ListView listview;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//이번 예제에서는 우선 직접 코딩으로 멤버정보를 입력하고

//다른 예제에서 추가/삭제 관련 작업을 해보겠습니다.

//비정상 회담(요즘 유명하기에 허락없이 도용합니다.-_-)멤버 정보 생성

datas.add( new MemberData("유세윤", "대한민국", R.drawable.korea));

datas.add( new MemberData("블레어", "호주", R.drawable.australia));

datas.add( new MemberData("기욤 패트리", "캐나다", R.drawable.canada));

datas.add( new MemberData("장위안", "중국", R.drawable.china));

datas.add( new MemberData("로빈", "프랑스", R.drawable.france));

datas.add( new MemberData("다니엘", "대한민국", R.drawable.germany));

datas.add( new MemberData("알베르토", "대한민국", R.drawable.italy));

datas.add( new MemberData("샘오취리", "대한민국", R.drawable.ghana));

//귀찮아서 다 못넣겠네요...-_-

//ListView 객체 찾아와서 참조

listview= (ListView)findViewById(R.id.listview);

//AdapterView의 일종인 ListView에 적용할 Adapter 객체 생성

//MemberData 객체의 정보들(이름, 국적, 이미지)를 적절하게 보여줄 뷰로 만들어주는 Adapter클래스 객체생성

//이 예제에서는 MemberDataAdapter.java 파일로 클래스를 설계하였음.

//첫번재 파라미터로 xml 레이아웃 파일을 객체로 만들어 주는 LayoutInflater 객체 얻어와서 전달..

//두번째 파라미터는 우리가 나열한 Data 배열..

MemberDataAdapter adapter= new MemberDataAdapter( getLayoutInflater() , datas);

//위에 만든 Adapter 객체를 AdapterView의 일종인 ListView에 설정.

listview.setAdapter(adapter);

}

}

 

여기까지 입니다.

다음 포스트에서는 ListView의 멤버를 추가하거나 삭제하는 예제를 소개하겠습니다.


반응형
반응형



어플을 종료하거나 특정작업을 수행할 때 사용자알림의 목적으로 다이얼 로그(Dialog)가 사용되는 경우가 있죠.


이번 예제소스는 안드로이드 어플에서 많이 사용되어지는 AlertDialog

사용자가 원하는 모양으로 커스터마이즈(Customize)하는 예제 입니다.


이 예제는 회원명단 추가를 위해 이름과 국적을 입력할 수 있는 Dialog를 만들어 보여주는 예제입니다.


'이름'은 EditText를 이용하여 입력받습니다.

'국적'은 RadioButton을 통해 선택하도록 하였습니다.


버튼을 누르면 멤버정보를 입력할 수 있는 Dialog를 보여주고

입력을 완료하면

메인화면의 TextView에 추가된 멤버들의 정보를 보여줍니다.


우선 어떻게 동작하는 지 먼저 살펴보고 소스코드를 소개하겠습니다.


실행화면


Button 1개와 TextView1개로 된 메인화면과 버튼을 클릭했을 때 보여지는 커스텀 다이얼로그(Custom AlertDialog) 

 


'이름'으로 'Hong' 입력하고 Korea Radio 버튼선택 후 '완료'버튼 클릭

 


다시 'Add Member...'버튼 클릭하여 'Robin' 입력완료

  


계속해서 '기욤 패드리' 입력 완료

 


입력을 취소할 때

 




먼저 메인 레이아웃 파일입니다.
Button 1개와 TextView 1개로 이루어진 간단한 레이아웃입니다.

 

 activity_main.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

    

    <Button 

        android:id="@+id/btn_add_member"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Add Member Dialog show"

        android:onClick="mOnClick"/>

    

    <TextView 

        android:id="@+id/text"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:textSize="18sp"

        android:textStyle="bold"

        android:padding="5dp"/>   


</LinearLayout>

 



다음으로 Custom Dialog에 보여질
'이름' 입력 EditText와 '국적'입력 RadioButton 들의 배치를 설계한
레이아웃 파일 입니다.

res폴더>>layout폴더>>dialog_addmember.xml 로 만들었습니다.

 

 dialog_addmember.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="250dp"

    android:layout_height="wrap_content"

    android:orientation="vertical"

    android:padding="5dp" >

    

    <LinearLayout 

        android:layout_width="match_parent"

        android:layout_height="30dp"

        android:orientation="horizontal"

        android:weightSum="5">

        

        <TextView 

            android:layout_width="0dp"

            android:layout_height="match_parent"

            android:layout_weight="1.5"

            android:text="NAME"

            android:textSize="12sp"

            android:gravity="center"/>

        

        <EditText

            android:id="@+id/dialog_edit" 

            android:layout_width="0dp"

            android:layout_height="match_parent"

            android:layout_weight="3.5"

            android:hint="input name"

            android:textSize="12sp"

            android:gravity="center"/>

        

    </LinearLayout>

    

    <LinearLayout 

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="horizontal"

        android:weightSum="5">

        

        <TextView 

            android:layout_width="0dp"

            android:layout_height="match_parent"

            android:layout_weight="1.5"

            android:text="NATION"

            android:textSize="12sp"

            android:gravity="center"/>

        

        <RadioGroup 

        android:id="@+id/dialog_rg"

        android:layout_width="0dp"

        android:layout_height="match_parent"

        android:layout_weight="3.5"

        android:orientation="vertical">            

        

        <RadioButton 

            android:id="@+id/dialog_rb_korea"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="KOREA"

            android:textSize="12sp"/>

        

        <RadioButton 

            android:id="@+id/dialog_rb_canada"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="CANADA"

            android:textSize="12sp"/>

        

        <RadioButton 

            android:id="@+id/dialog_rb_france"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="FRANCE"

            android:textSize="12sp"/>

        

        <RadioButton 

            android:id="@+id/dialog_rb_mexico"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="MEXICO"

            android:textSize="12sp"/>

        

        <RadioButton 

            android:id="@+id/dialog_rb_poland"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="POLAND"

            android:textSize="12sp"/>

        

        <RadioButton 

            android:id="@+id/dialog_rb_saudi"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="SAUDI ARABIA"

            android:textSize="12sp"/>

        

    </RadioGroup>

        

    </LinearLayout>


</LinearLayout>  

 



다음은 소스파일입니다.
주석이 많아서 그렇지 사실 작업내용은 얼마 안됩니다.
빽빽한 코드의 모습에 미리 한숨쉬지 않길 바랍니다.

 MainActivity.java


public class MainActivity extends Activity {

TextView text;//Dialog를 통해 입력된 멤버의 정보를 출력하는 TextView 참조변수

String str="";//빈 문자열 String 객체


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

text= (TextView)findViewById(R.id.text);

}

//onClick 속성이 부여된 View를 클릭했을 때 자동으로 호출되는 메소드

public void mOnClick(View v){

switch( v.getId() ){

case R.id.btn_add_member://멤버 추가(데이터 추가)

//Dialog에서 보여줄 입력화면 View 객체 생성 작업

//Layout xml 리소스 파일을 View 객체로 부불려 주는(inflate) LayoutInflater 객체 생성

LayoutInflater inflater=getLayoutInflater();

//res폴더>>layout폴더>>dialog_addmember.xml 레이아웃 리소스 파일로 View 객체 생성

//Dialog의 listener에서 사용하기 위해 final로 참조변수 선언

final View dialogView= inflater.inflate(R.layout.dialog_addmember, null);

//멤버의 세부내역 입력 Dialog 생성 및 보이기

AlertDialog.Builder buider= new AlertDialog.Builder(this); //AlertDialog.Builder 객체 생성 

buider.setTitle("Member Information"); //Dialog 제목

buider.setIcon(android.R.drawable.ic_menu_add); //제목옆의 아이콘 이미지(원하는 이미지 설정)

buider.setView(dialogView); //위에서 inflater가 만든 dialogView 객체 세팅 (Customize)

buider.setPositiveButton("Complite", new OnClickListener() {

//Dialog에 "Complite"라는 타이틀의 버튼을 설정

@Override

public void onClick(DialogInterface dialog, int which) {

// TODO Auto-generated method stub

//멤버 정보의 입력을 완료하고 TextView에 추가 하도록 하는 작업 수행

//dialogView 객체 안에서 NAME을 입력받는 EditText 객체 찾아오기(주의: dialaogView에서 find 해야함)

EditText edit_name= (EditText)dialogView.findViewById(R.id.dialog_edit);

//dialogView 객체 안에서 NATION을 입력받는 RadioGroup 객체 찾아오기

RadioGroup rg= (RadioGroup)dialogView.findViewById(R.id.dialog_rg);

//EditText에 입력된 이름 얻어오기

String name= edit_name.getText().toString();

//선택된 RadioButton의 ID를 RadioGroup에게 얻어오기

int checkedId= rg.getCheckedRadioButtonId();

//Check 된 RadioButton의 ID로 라디오버튼 객체 찾아오기

RadioButton rb= (RadioButton)rg.findViewById(checkedId);

String nation= rb.getText().toString();//RadionButton의 Text 얻어오기

//TextView의 이전 Text에 새로 입력된 멤버의 데이터를 추가하기

//TextView로 멤버리스트를 보여주는 것은 바람직하지 않음.다음 포스트에서 ListView로 처리합니다.

String s= name+"   "+nation+"\n";

str+= s;

text.setText(str);

//TextView에 추가작업을 완료 하였기에 '완료'했다는 메세지를 Toast로 출력

Toast.makeText(MainActivity.this, "새로운 멤버를 추가했습니다", Toast.LENGTH_SHORT).show();

}

});

buider.setNegativeButton("Cancel", new OnClickListener() {

//Dialog에 "Cancel"이라는 타이틀의 버튼을 설정

@Override

public void onClick(DialogInterface dialog, int which) {

// TODO Auto-generated method stub

//멤버 정보의 입력을 취소하고 Dialog를 종료하는 작업

//취소하였기에 특별한 작업은 없고 '취소'했다는 메세지만 Toast로 출력

Toast.makeText(MainActivity.this, "멤버 추가를 취소합니다", Toast.LENGTH_SHORT).show();

}

});

//설정한 값으로 AlertDialog 객체 생성

AlertDialog dialog=buider.create();

//Dialog의 바깥쪽을 터치했을 때 Dialog를 없앨지 설정

dialog.setCanceledOnTouchOutside(false);//없어지지 않도록 설정

//Dialog 보이기

dialog.show();

break;

}//switch

}//mOnClickMethod

}


 

 

반응형
반응형



이전 까지 ListView를 통해 많은 데이터를 표시하는  예제를 소개했었습니다.


리스트뷰는 많은 어플에서 실제로 활용도가 높아

많이 사용됩니다.


특히 액티비티 화면전체가 리스트형태로 되어 있는 경우도 많습니다.

해서 ListView를 만들필요없이

액티비티(Activity)가 기본적으로 ListView를 보유하도록 만들었습니다.


이렇게 만들어진 것이 ListActivity 입니다.


즉, ListView가 이미 설정되어 있는 액티비티라고 보면 됩니다.


여기서 중요한 것은

 이미 이 액티비티는 화면에 보여 줄 View객체가 설정되어 있다는 것입니다.


다들 아시다시피

액티비티는 setContentView() 메소드를 통해 보여줄 View를 설정합니다.

ListActivity는 이 작업을 하지 않는다는 거죠.


코드가 간단하니 소스코드만 소개하겠습니다.

참고로 setContentView()메소드가 없는 만큼 xml 레이아웃 파일은 필요없네요.


리스트를 보여주고 선택하면 해당 문자열 데이터가 Toast로 출력되는 예제소소입니다.



리스트 액티비티(ListActivity)에서 주요한 역할을 하는 코딩 부분은 굵게 표시했습니다. 

 MainActivity.java


public class MainActivity extends ListActivity {

//ListActivity- Activity가 보여줄 View로 이미 ListView를 설정한 Activity

//일반 Activity와 다르게 setContentView()메소드를 사용하지 않음

//이미 ListView 객체가 설정되어 있음

//대량의 문자열 데이터를 저장할 Arraylist 객체 생성

ArrayList<String> mDatas= new ArrayList<String>();


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//여기에 자동으로 써있는 setContentView()메소드 삭제

//문자열 데이터 ArrayList에 추가

mDatas.add("KOREA");

mDatas.add("CANADA");

mDatas.add("FRANCE");

mDatas.add("MEXICO");

mDatas.add("POLAND");

mDatas.add("SAUDI ARABIA");

//ListView가 보여줄 뷰를 만들어내는 Adapter 객체 생성

//ArrayAdapter : 문자열 데이터들을 적절한 iew로 1:1로 만들어서 List형태로 ListView에 제공하는 객체

//첫번째 파라미터 : Context객체 ->MainActivity가 Context를 상속했기 때문에 this로 제공 가능

//두번째 파라미터 : 문자열 데이터를 보여줄 뷰. ListView에 나열되는 하나의 아이템 단위의 뷰 모양

//세번째 파라미터 : adapter가 뷰로 만들어줄 대량의 데이터들

//본 예제에서는 문자열만 하나씩 보여주면 되기 때문에 두번째 파라미터의 뷰 모먕은 Android 시스템에서 제공하는

//기본 Layout xml 파일을 사용함.

ArrayAdapter adapter= new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas);

//ListActivity가 가지고 있는 ListView에 Adapter 설정

//getListView() 메소드로 보유하고 있는 ListView 객체를 얻어올 수 있음

setListAdapter(adapter);

}

//ListActivity의 List를 클릭했을 때 자동으로 호출되는 메소드

//첫번째 파라미터 : ListActivity가 보유하고 있는 ListView 객체

//두번째 파라미터 : List중에 선택된 아이템 뷰(View)

//세번째 파라미터 : 클릭된 아이템의 위치

//네번째 파라미터 : 클릭된 아이템의 아이디(기본값은 position과 동일)

@Override

protected void onListItemClick(ListView l, View v, int position, long id) {

// TODO Auto-generated method stub

Toast.makeText(MainActivity.this, mDatas.get(position), Toast.LENGTH_SHORT).show();

super.onListItemClick(l, v, position, id);

}

}




결과화면


   


반응형
반응형



이전 포스트에서 소개한

ListView에 Context Menu 달기 예제에서

Context Menu는 오래 누르면 나오는 메뉴입니다.


그래서

ListView의 한 항목을 오래 누르는 것을 감지하여

자동으로 콜백 메소드를 호출하는

OnItemLongClickListener를 이용해서 이전 예제를 만들어 보겠습니니다.


선택한 항목에 메뉴가 만들어져야 하기에

Popup Menu를 사용하였습니다.


이전 Context Menu 예제에서는 메뉴가 보여지는 위치가

누른 항목과 상관없이 가운데 였습니다.


이에 비해 이번 예제에서 메뉴가 나타나는 위치는

선택한 항목에서 보여지게 되어 보다

해당 항목의 메뉴라는 느낌이 명확합니다.


다른 부분은 모두 이전 예제와 같고 소스코드만 다르기에

결과만 잠시 보고

소스 코드만 포스팅합니다.


실행화면


Context Menu와 ItemLongClick을 이용한 Popup Menu 차이

  

 



이전 포스트의 Context 메뉴관련 코드를 모두 제거하고

LongClick에 반응하는 코드를 추가합니다.


굵은 글씨가 새로 추가한 코드입니다.

 

 MainActivity.java


public class MainActivity extends Activity {

//대량의 문자열 데이터를 저장할 Arraylist 객체 생성

ArrayList<String> mDatas= new ArrayList<String>();

ListView listview; //ListView 참조변수


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//문자열 데이터 ArrayList에 추가

mDatas.add("KOREA");

mDatas.add("CANADA");

mDatas.add("FRANCE");

mDatas.add("MEXICO");

mDatas.add("POLAND");

mDatas.add("SAUDI ARABIA");

//ListView가 보여줄 뷰를 만들어내는 Adapter 객체 생성

//ArrayAdapter : 문자열 데이터들을 적절한 iew로 1:1로 만들어서 List형태로 ListView에 제공하는 객체

//첫번째 파라미터 : Context객체 ->MainActivity가 Context를 상속했기 때문에 this로 제공 가능

//두번째 파라미터 : 문자열 데이터를 보여줄 뷰. ListView에 나열되는 하나의 아이템 단위의 뷰 모양

//세번째 파라미터 : adapter가 뷰로 만들어줄 대량의 데이터들

//본 예제에서는 문자열만 하나씩 보여주면 되기 때문에 두번째 파라미터의 뷰 모먕은 Android 시스템에서 제공하는

//기본 Layout xml 파일을 사용함.

ArrayAdapter adapter= new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas);

listview= (ListView)findViewById(R.id.listview);

listview.setAdapter(adapter); //위에 만들어진 Adapter를 ListView에 설정 : xml에서 'entries'속성

//ListView의 아이템 하나가 클릭되는 것을 감지하는 Listener객체 설정 (Button의 OnClickListener와 같은 역할)

listview.setOnItemClickListener(listener);

//Listview의 아이템 하나가 오래 눌러지는 것을 감지하는 Listener객체 생성(위의 OnItemClickListener같은 역할)

listview.setOnItemLongClickListener(new OnItemLongClickListener() {

//ListView의 아이템 중 하나가 오래 클릭될 때 호출되는 메소드

//첫번째 파라미터 : 오래 눌러진 아이템을 보여주고 있는 AdapterView 객체(여기서는 ListView객체)

//두번째 파라미터 : 오래 눌러진 아이템 뷰

//세번째 파라미터 : 오래 눌러진 아이템의 위치(ListView이 첫번째 아이템(가장위쪽)부터 차례대로 0,1,2,3.....)

//네번재 파리미터 : 오래 눌러진 아이템의 아이디(특별한 설정이 없다면 세번째 파라이터인 position과 같은 값)

@Override

public boolean onItemLongClick(AdapterView<?> parent, View view,

int position, long id) {

// TODO Auto-generated method stub

//PopupMenu객체 생성. 

     //생성자함수의 첫번재 파라미터 : Context

     //생성자함수의 두번째 파라미터 : Popup Menu를 붙일 anchor 뷰

     PopupMenu popup= new PopupMenu(MainActivity.this, view);//view는 오래 눌러진 뷰를 의미

    

     //Popup Menu에 들어갈 MenuItem 추가.

     //이전 포스트의 컨텍스트 메뉴(Context menu)처럼 xml 메뉴 리소스 사용

     //첫번재 파라미터 : res폴더>>menu폴더>>menu_listview.xml파일 리소스

     //두번재 파라미터 : Menu 객체->Popup Menu 객체로 부터 Menu 객체 얻어오기

     getMenuInflater().inflate(R.menu.menu_listview, popup.getMenu());

    

     //Popup menu의 메뉴아이템을 눌렀을  때 보여질 ListView 항목의 위치

//Listener 안에서 사용해야 하기에 final로 선언

final int index= position;

     //Popup Menu의 MenuItem을 클릭하는 것을 감지하는 listener 설정

     popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {

@Override

public boolean onMenuItemClick(MenuItem item) {

// TODO Auto-generated method stub

//선택된 Popup Menu의  아이템아이디를 구별하여 원하는 작업 수행

//예제에서는 선택된 ListView의 항목(String 문자열) data와 해당 메뉴이름을 출력함

switch( item.getItemId() ){

case R.id.modify:

Toast.makeText(MainActivity.this, mDatas.get(index)+" Modify", Toast.LENGTH_SHORT).show(); break;

case R.id.delete:

Toast.makeText(MainActivity.this, mDatas.get(index)+" Delete", Toast.LENGTH_SHORT).show();

break;

case R.id.info:

Toast.makeText(MainActivity.this, mDatas.get(index)+" Info", Toast.LENGTH_SHORT).show();

break;

}

return false;

}

});

        

     popup.show();//Popup Menu 보이기 

return false;

}

});

}

//ListView의 아이템 하나가 클릭되는 것을 감지하는 Listener객체 생성 (Button의 OnClickListener와 같은 역할)

OnItemClickListener listener= new OnItemClickListener() {

//ListView의 아이템 중 하나가 클릭될 때 호출되는 메소드

//첫번째 파라미터 : 클릭된 아이템을 보여주고 있는 AdapterView 객체(여기서는 ListView객체)

//두번째 파라미터 : 클릭된 아이템 뷰

//세번째 파라미터 : 클릭된 아이템의 위치(ListView이 첫번째 아이템(가장위쪽)부터 차례대로 0,1,2,3.....)

//네번재 파리미터 : 클릭된 아이템의 아이디(특별한 설정이 없다면 세번째 파라이터인 position과 같은 값)

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

// TODO Auto-generated method stub

//클릭된 아이템의 위치를 이용하여 데이터인 문자열을 Toast로 출력

Toast.makeText(MainActivity.this, mDatas.get(position), Toast.LENGTH_SHORT).show();

}

};

}




반응형
반응형



이전 포스트에서 리스트 뷰(ListView)를 만들고

리스트 중 하나의 항목을 클릭하면 해당 데이터를 Toast로 표시하는 예제를 소개했습니다.


이번엔 실제 어플에 좀더 많이 사용되는 예제를 소개합니다.


실제 ListView를 사용하는 어플들을 보면

해당 항목을 오래 눌렀을 때 별도의 메뉴가 팍! 나타나는 것을 보셨을 겁니다.


가장 대표적인 경우가 문자(메세제) 목록 중 하나를 삭제하거나 할 때

해당 목록을 오래 누르고 있으면 메뉴가 팍! 올라와서 선택할 수 있는 것을 말합니다.

많이 사용되겠죠.


Context 메뉴는 이미 이전 포스트에서 소개한 적이 있었습니다.

이를 ListView에 적용해 보도록 하겠습니다.


먼저 동작 결과를 보겠습니다.


스크롤 되는 ListView

  



ListView의 첫번째 항목을 길게 눌러서 Context 메뉴 표시

   



ListView의 세번째 항목을 길게 눌러서 Context 메뉴 표시

   



ListView의 마지막 항목을 길게 눌러서 Context 메뉴 표시

   




소스파일들은 이전 포스트의 아이템 클릭 예제에 몇가지만 추가했습니다.



레이아웃 파일은 이전 포스트와 마찬가지로 ListView 하나입니다. 

 activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >


    <ListView 

        android:id="@+id/listview"

        android:layout_width="match_parent"

        android:layout_height="200dp"/>


</RelativeLayout>


이번 예제는 Context Menu가 있기에 Menu설계를 위해

res폴더 >> menu폴더 >> menu_listview.xml을 만들었습니다.

(이전 포스트의 Context Menu 참고)


메뉴아이템을 설계하는 XML 리소스를 만듭니다.

(이전 옵션메뉴 포스트의 xml파일을 가져와도 됨)

res폴더 안에 'menu'라는 이름으로 폴더를 만드세요(절대 이름 틀리면 안됨)

만들어진 menu폴더안에 menu_listview.xml 파일을 하나 추가하세요.


메뉴 XML 리소스 파일

 mainmenu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    

    <item android:id="@+id/modify"

        android:title="Modify"/>

    

    <item android:id="@+id/delete"

        android:title="Delete"/>

    

    <item android:id="@+id/info"

        android:title="Info"/>    


</menu>

   


소스 코드는 이전 코드에서 새로 추가만 햇습니다.

이전 예제의 클릭은 당연히 동작하겠죠?


굵은 글씨가 새로 추가된 코드(code) 입니다. 

 MainActivity.java


public class MainActivity extends Activity {

//대량의 문자열 데이터를 저장할 Arraylist 객체 생성

ArrayList<String> mDatas= new ArrayList<String>();

ListView listview; //ListView 참조변수


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//문자열 데이터 ArrayList에 추가

mDatas.add("KOREA");

mDatas.add("CANADA");

mDatas.add("FRANCE");

mDatas.add("MEXICO");

mDatas.add("POLAND");

mDatas.add("SAUDI ARABIA");

//ListView가 보여줄 뷰를 만들어내는 Adapter 객체 생성

//ArrayAdapter : 문자열 데이터들을 적절한 iew로 1:1로 만들어서 List형태로 ListView에 제공하는 객체

//첫번째 파라미터 : Context객체 ->MainActivity가 Context를 상속했기 때문에 this로 제공 가능

//두번째 파라미터 : 문자열 데이터를 보여줄 뷰. ListView에 나열되는 하나의 아이템 단위의 뷰 모양

//세번째 파라미터 : adapter가 뷰로 만들어줄 대량의 데이터들

//본 예제에서는 문자열만 하나씩 보여주면 되기 때문에 두번째 파라미터의 뷰 모먕은 Android 시스템에서 제공하는

//기본 Layout xml 파일을 사용함.

ArrayAdapter adapter= new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas);

listview= (ListView)findViewById(R.id.listview);

listview.setAdapter(adapter); //위에 만들어진 Adapter를 ListView에 설정 : xml에서 'entries'속성

//ListView의 아이템 하나가 클릭되는 것을 감지하는 Listener객체 설정 (Button의 OnClickListener와 같은 역할)

listview.setOnItemClickListener(listener);

//ListView를 Context 메뉴로 등록

registerForContextMenu(listview);

}

//Context 메뉴로 등록한 View(여기서는 ListView)가 처음 클릭되어 만들어질 때 호출되는 메소드

@Override

public void onCreateContextMenu(ContextMenu menu, View v,

ContextMenuInfo menuInfo) {

// TODO Auto-generated method stub

//res폴더의 menu플더안에 xml로 MenuItem추가하기.

//mainmenu.xml 파일을 java 객체로 인플레이트(inflate)해서 menu객체에 추가

getMenuInflater().inflate(R.menu.menu_listview, menu);

super.onCreateContextMenu(menu, v, menuInfo);

}

//Context 메뉴로 등록한 View(여기서는 ListView)가 클릭되었을 때 자동으로 호출되는 메소드

public boolean onContextItemSelected(MenuItem item) {

//AdapterContextMenuInfo

//AdapterView가 onCreateContextMenu할때의 추가적인 menu 정보를 관리하는 클래스

//ContextMenu로 등록된 AdapterView(여기서는 Listview)의 선택된 항목에 대한 정보를 관리하는 클래스

AdapterContextMenuInfo info= (AdapterContextMenuInfo)item.getMenuInfo();

int index= info.position; //AdapterView안에서 ContextMenu를 보여즈는 항목의 위치

//선택된 ContextMenu의  아이템아이디를 구별하여 원하는 작업 수행

//예제에서는 선택된 ListView의 항목(String 문자열) data와 해당 메뉴이름을 출력함

switch( item.getItemId() ){

case R.id.modify:

Toast.makeText(this, mDatas.get(index)+" Modify", Toast.LENGTH_SHORT).show();

break;

case R.id.delete:

Toast.makeText(this, mDatas.get(index)+" Delete", Toast.LENGTH_SHORT).show();

break;

case R.id.info:

Toast.makeText(this, mDatas.get(index)+" Info", Toast.LENGTH_SHORT).show();

break;

}

return true;

};

//ListView의 아이템 하나가 클릭되는 것을 감지하는 Listener객체 생성 (Button의 OnClickListener와 같은 역할)

OnItemClickListener listener= new OnItemClickListener() {

//ListView의 아이템 중 하나가 클릭될 때 호출되는 메소드

//첫번째 파라미터 : 클릭된 아이템을 보여주고 있는 AdapterView 객체(여기서는 ListView객체)

//두번째 파라미터 : 클릭된 아이템 뷰

//세번째 파라미터 : 클릭된 아이템의 위치(ListView이 첫번째 아이템(가장위쪽)부터 차례대로 0,1,2,3.....)

//네번재 파리미터 : 클릭된 아이템의 아이디(특별한 설정이 없다면 세번째 파라이터인 position과 같은 값)

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

// TODO Auto-generated method stub

//클릭된 아이템의 위치를 이용하여 데이터인 문자열을 Toast로 출력

Toast.makeText(MainActivity.this, mDatas.get(position), Toast.LENGTH_SHORT).show();

}

};

}




반응형
반응형



이전 포스트에서 Java에서 생성된 데이터들을 

리스트 뷰(ListView)에 표시하는 예제 소스를 보여드렸습니다.


이번 예제소스는


리스트 뷰(ListView)에 표시된 데이터들(여기서는 문자열들(Strings))을

선택했을 때 해당 아이템의 문자열을 Toast로 출력하는 예제소스입니다.


이전 예제에서 Java 소스만 조금 추가하면 됩니다.


Button 뷰(View) 작업할 때 OnClickListener를 사용해 보셨다면

아주 쉬울 겁니다.


ListView에 OnItemClickListener 만 설정해주시면 됩니다.


xml파일을 이전 포스트와 동일하면

Java 파일도 이전 포스트에서 클릭처리 부분만 추가하였습니다.


 

 activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >


    <ListView 

        android:id="@+id/listview"

        android:layout_width="match_parent"

        android:layout_height="200dp"/>


</RelativeLayout>



굵은 글씨가 새로 추가된 코드(code) 입니다. 

 MainActivity.java

 public class MainActivity extends Activity {

//대량의 문자열 데이터를 저장할 Arraylist 객체 생성

ArrayList<String> mDatas= new ArrayList<String>();

ListView listview; //ListView 참조변수


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//문자열 데이터 ArrayList에 추가

mDatas.add("KOREA");

mDatas.add("CANADA");

mDatas.add("FRANCE");

mDatas.add("MEXICO");

mDatas.add("POLAND");

mDatas.add("SAUDI ARABIA");

//ListView가 보여줄 뷰를 만들어내는 Adapter 객체 생성

//ArrayAdapter : 문자열 데이터들을 적절한 iew로 1:1로 만들어서 List형태로 ListView에 제공하는 객체

//첫번째 파라미터 : Context객체 ->MainActivity가 Context를 상속했기 때문에 this로 제공 가능

//두번째 파라미터 : 문자열 데이터를 보여줄 뷰. ListView에 나열되는 하나의 아이템 단위의 뷰 모양

//세번째 파라미터 : adapter가 뷰로 만들어줄 대량의 데이터들

//본 예제에서는 문자열만 하나씩 보여주면 되기 때문에 두번째 파라미터의 뷰 모먕은 Android 시스템에서 제공하는

//기본 Layout xml 파일을 사용함.

ArrayAdapter adapter= new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas);

listview= (ListView)findViewById(R.id.listview);

listview.setAdapter(adapter); //위에 만들어진 Adapter를 ListView에 설정 : xml에서 'entries'속성

//ListView의 아이템 하나가 클릭되는 것을 감지하는 Listener객체 설정 (Button의 OnClickListener와 같은 역할)

listview.setOnItemClickListener(listener);

}

//ListView의 아이템 하나가 클릭되는 것을 감지하는 Listener객체 생성 (Button의 OnClickListener와 같은 역할)

OnItemClickListener listener= new OnItemClickListener() {

//ListView의 아이템 중 하나가 클릭될 때 호출되는 메소드

//첫번째 파라미터 : 클릭된 아이템을 보여주고 있는 AdapterView 객체(여기서는 ListView객체)

//두번째 파라미터 : 클릭된 아이템 뷰

//세번째 파라미터 : 클릭된 아이템의 위치(ListView이 첫번째 아이템(가장위쪽)부터 차례대로 0,1,2,3.....)

//네번재 파리미터 : 클릭된 아이템의 아이디(특별한 설정이 없다면 세번째 파라이터인 position과 같은 값)

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

// TODO Auto-generated method stub

//클릭된 아이템의 위치를 이용하여 데이터인 문자열을 Toast로 출력

Toast.makeText(MainActivity.this, mDatas.get(position), Toast.LENGTH_SHORT).show();

}

};

}



결과화면입니다. 클릭해서 토스트(Toast) 출력도 합니다.


  


  



반응형
반응형



이전 포스트에서는 대량의 데이터가 xml에 있을 때의 ListView 예제였습니다.


이번 예제는 대량의 데이터가 .java 에서 생산된 경우의 예제입니다.


실제로 대다수의 어플을 만들 때 데이터들을 xml에서 미리 만드는 경우보다는

데이터 베이스에 있거나 이번 예제처럼 java 언어에서 직접 만들어지는 경우가 많습니다.


Java에서 ListView 객체에 데이터를 설정할 때는

대량의 데이터를 그에 맞는 적절한 뷰로 자동으로 변환하는 'Adapter' 객체가 필요합니다.

우선 간단한 문자열 데이터의 배열이기에 단순 리스트 형태로 변환하는

ArrayAdapter를 만들어 ListView에 보여주도록 하겠습니다.


간단하니 코드만 소개합니다.


 activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >


    <ListView 

        android:id="@+id/listview"

        android:layout_width="match_parent"

        android:layout_height="200dp"/>


</RelativeLayout>



 

 MainActivity.java

 public class MainActivity extends Activity {

//대량의 문자열 데이터를 저장할 Arraylist 객체 생성

ArrayList<String> mDatas= new ArrayList<String>();

ListView listview; //ListView 참조변수


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//문자열 데이터 ArrayList에 추가

mDatas.add("KOREA");

mDatas.add("CANADA");

mDatas.add("FRANCE");

mDatas.add("MEXICO");

mDatas.add("POLAND");

mDatas.add("SAUDI ARABIA");

//ListView가 보여줄 뷰를 만들어내는 Adapter 객체 생성

//ArrayAdapter : 문자열 데이터들을 적절한 iew로 1:1로 만들어서 List형태로 ListView에 제공하는 객체

//첫번째 파라미터 : Context객체 ->MainActivity가 Context를 상속했기 때문에 this로 제공 가능

//두번째 파라미터 : 문자열 데이터를 보여줄 뷰. ListView에 나열되는 하나의 아이템 단위의 뷰 모양

//세번째 파라미터 : adapter가 뷰로 만들어줄 대량의 데이터들

//본 예제에서는 문자열만 하나씩 보여주면 되기 때문에 두번째 파라미터의 뷰 모먕은 Android 시스템에서 제공하는

//기본 Layout xml 파일을 사용함.

ArrayAdapter adapter= new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas);

listview= (ListView)findViewById(R.id.listview);

listview.setAdapter(adapter); //위에 만들어진 Adapter를 ListView에 설정 : xml에서 'entries'속성

}

}



결과화면입니다. 스크롤도 확인하도록 ListView 크기보다 데이터 양을 많이 했습니다.


  


반응형
반응형



문자열 배열이나 데이터베이스의 자료처럼

대량의 데이터를 화면에 나타낼때 유용한 뷰 그룹(View Group)인 어뎁터 뷰(Adapter View)


이 아답터 뷰는 보여주는 형태에 따라 몇가지 종류가 있죠.


1. 가장 많이 사용하는 단순 목록 나열 형식의 ListView

2. 콤보박스나 드롭다운박스로 불려지는 Spinner

3. 사진이나 그림들을 격자 형태로 보여줄 때 유요한 GridView

4. Gellary도 있지만 요즘은 GridView로 대체




우선 가장 많이 사용하는 ListView에 대한 예제 소스입니다.


먼저 대량의 데이터가 단순히 문자열 배열일때의 예제입니다.


문자열 배열을 res폴더>>values>>arrays.xml 리소스 파일에 만들어 놨습니다.


잘 알시다시피 안드로이드는 문자열(String)도 xml 리소스(Resource)로 처리하는 것을 선호합니다.

당연히 문자열 배열(String-Array)도 xml 리소스로 만들 수 있겠죠.


단, 단일 문자열은 strings.xml에 만들지만

배열은 arrays.xml에 만들어야 한다는 것만 주의하세요.


혹시나 해서 만드는 과정을 그림으로 소개하겠습니다.



  



파일이름이 틀리면 안됩니다. 주의하세요.



만들어지 arrays.xml 파일안에 문자열 배열 하나를 추가합니다.

 arrays.xml

 <resources>

    <string-array name="datas">

        <item >KOREA</item>

        <item >CANADA</item>

        <item >FRANCE</item>

        <item >MEXICO</item>        

    </string-array>

    

</resources>


이렇게 만들어진 문자열 배열 리소스 파일을

ListView의 'android:entries:'속성에 설정합니다.


 

 activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >


    <ListView 

        android:id="@+id/listview"

        android:layout_width="match_parent"

        android:layout_height="300dp"

        android:entries="@array/datas"/>


</RelativeLayout>


'@array/datas' 에서 datas가 arrays.xml 파일안에 만든

문자열 배열의 'name='속성에 지정한 이름입니다.


가장 간단하게 문자열 데이터들을 화면에 표시하는 방법입니다.


실행결과화면입니다.


 


ListView 의 크기보다 보여줘야할 데이터의 양이 많으면

자동으로 스크롤이 만들어집니다.


다음 포스트에서는 Java 언어에서 문자열 배열을 만들어서

ListView에 표시하는 예제를 포스팅합니다.

반응형
반응형



Popup Menu : 특정 명령에 따라 특정 위치에 팝업(Popup)되어 서브 메뉴용도로 사용할 수 있는 메뉴


버튼(Button) 을 누르면 그 버튼에 Popup Menu가 나타납니다.

특정 메뉴 아이템을 선택하면 해당하는 Toast가 표시되는 예제소스입니다.



먼저 실행 화면입니다.


         메인화면                             버튼 클릭으로 Popup Menu 발생

  


  

 팝업 메뉴(Popup Menu)의 각 menuItem 선택시의 Toast



소스코드

 MainActivity.java

 public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

//Button 클릭시에 자동으로 호출되는 callback Method...

    public void mOnClick(View v){

    

     switch( v.getId() ){

     case R.id.btn_popupmenu:

    

     //PopupMenu객체 생성. 

     //생성자함수의 첫번재 파라미터 : Context

     //생성자함수의 두번째 파라미터 : Popup Menu를 붙일 anchor 뷰

     PopupMenu popup= new PopupMenu(this, v);//v는 클릭된 뷰를 의미

    

     //Popup Menu에 들어갈 MenuItem 추가.

     //이전 포스트의 컨텍스트 메뉴(Context menu)처럼 xml 메뉴 리소스 사용

     //첫번재 파라미터 : res폴더>>menu폴더>>mainmenu.xml파일 리소스

     //두번재 파라미터 : Menu 객체->Popup Menu 객체로 부터 Menu 객체 얻어오기

     getMenuInflater().inflate(R.menu.mainmenu, popup.getMenu());

    

     //Popup Menu의 MenuItem을 클릭하는 것을 감지하는 listener 설정

     popup.setOnMenuItemClickListener(listener);

         

     popup.show();//Popup Menu 보이기

    

     break;

     }

    

    }//mOnClick Method..

  

    //Popup Menu의 MenuItem을 클릭하는 것을 감지하는 listener 객체 생성

    //import android.widget.PopupMenu.OnMenuItemClickListener 가 되어있어야 합니다.

    //OnMenuItemClickListener 클래스는 다른 패키지에도 많기 때문에 PopupMenu에 반응하는 패키지를 임포트하셔야 합니다.

    OnMenuItemClickListener listener= new OnMenuItemClickListener() {

@Override

public boolean onMenuItemClick(MenuItem item) {

// TODO Auto-generated method stub

switch( item.getItemId() ){//눌러진 MenuItem의 Item Id를 얻어와 식별

case R.id.save:

Toast.makeText(MainActivity.this, "SAVE", Toast.LENGTH_SHORT).show();

break;

case R.id.search:

Toast.makeText(MainActivity.this, "SEARCH", Toast.LENGTH_SHORT).show();

break;

case R.id.setting:

Toast.makeText(MainActivity.this, "SETTING", Toast.LENGTH_SHORT).show();

break;

}

return false;

}

};

    

}




메뉴아이템을 설계하는 XML 리소스를 만듭니다.

(이전 옵션메뉴 포스트의 xml파일을 가져와도 됨)

res폴더 안에 'menu'라는 이름으로 폴더를 만드세요(절대 이름 틀리면 안됨)

만들어진 menu폴더안에 mainmenu.xml 파일을 하나 추가하세요.


메뉴 XML 리소스 파일

 mainmenu.xml

 <menu xmlns:android="http://schemas.android.com/apk/res/android" >

    

    <item

        android:id="@+id/save" 

        android:title="SAVE"

        android:icon="@android:drawable/ic_menu_save" />

    

    <item

        android:id="@+id/search" 

        android:title="SEARCH"

        android:icon="@android:drawable/ic_menu_search" />

    

    <item

        android:id="@+id/setting" 

        android:title="SETTING"

        android:icon="@android:drawable/ic_menu_edit" />


</menu>

   

반응형

+ Recent posts