안드로이드/프로그래밍

[안드로이드] 커스텀 리스트뷰 만들기 #2 [다이얼로그 및 레이아웃 추가]

RBWSN 2015. 3. 2. 04:24
728x90
이번장에서는 이미지를 연결하는방법과 새로운 인텐트를 생성하여 커스텀 리스트뷰에 2개의 레이아웃을 따로 넣을수 있게해본다.

먼저 이미지를 연결하려면 캡쳐나 갤러리를 받아와야한다.
먼저 사진찍기나 갤러리를 여는법의 코드를 보자.


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
32
33
34
35
36
37
38
39
public void MemoDialog(){ // 다이얼 박스 생성
        
        AlertDialog.Builder builder = new AlertDialog.Builder(this); // 액티비티 받아옴
        builder.setTitle("이미지 선택") // 다이얼박스 제목
        .setItems(items, new DialogInterface.OnClickListener() { // 아이템 클릭리스너
            
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                switch(which){
                case 0: // 사진찍기호출 
                    long now = System.currentTimeMillis();// 현재 시작을 알아옴
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); //시간 포맷
                    nowString = dateFormat.format(now); // 포맷과 현재 시각을 연결
                    mPath = Environment.getExternalStorageDirectory().getAbsolutePath() +"/" +  nowString + ".jpg"; //저장할 위치
                    
                    Log.i("now", nowString);
                    
                    
                    f= new File(mPath); // 저장위치 파일로 연결
                    
                    Dialogintent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 이미지 캡쳐실행
                    Dialogintent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); // 파일저장
                    startActivityForResult(Dialogintent, CALL_CAMERA); //  액티비티 호출
                    
                    break;
                case 1: // 갤러리 호출
                    Dialogintent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // 갤러리 받아오기
                    startActivityForResult(Dialogintent, CALL_GALLERY); // 갤러리 호출
                    break;
                    
                    
                }
                
            }
        });
        AlertDialog dialog = builder.create();
        dialog.show();
    }
cs
다이얼박스로 생성을 하였다 .
현재 의 시간을 포맷하여 지금의 시간으로 연결을 하였다.
Intent의  첫번째 미디어스토어의 액션 캡쳐로 이미지 캡쳐 프로그램을 열수있고 두번째의 액션픽으로 미디어 스토어와연결해서 갤러리의 사진들을 받아올수 있다.


그리고 저장과 함께 갤러리를 이미지뷰와 연동시키려면 startActivityForResult로 액티비티를 호출하여  그에따른 셋팅을해야하는데 그것은 on AcxtivityuResult로 다시 받아올수가 있다.


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
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        if(resultCode == RESULT_OK){
            switch(requestCode){
            case CALL_CAMERA:
                Log.i("setImg""ok");                
                memoImg.setImageBitmap(BitmapFactory.decodeFile(mPath));                
                ImageUp(); // 갤러리 갱신
                break;
                
            case CALL_GALLERY:
                try {
                    memoImg.setImageBitmap(MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData()));
                    Uri aa2 = data.getData();
                    mPath = getRealPathFromURI(aa2);
                    Log.i("갤러리 사진호출완료", mPath);
                    
                } catch (Exception e) {
                    // TODO: handle exception
                    
                }
                
                break;
                
            }
        }
    }
cs
아까 갤러리의 사진을 찍을때 지금의 시간을 mPath의 변수로 저장했으므로 그것을 decodeFile로 이미지를 셋팅한다.
그리고 사진을 찍게된다면 이제 갤러리를 갱신해주어야하는데 4.4 킷캣버젼부터는 일괄 방송으로는 갱신이안되고 무조건 파일의 이름을 넘겨 주어야한다.

ImageUp이라는 함수를 생성하여 만들었다.
그함수의 코드를 보자.

1
2
3
4
5
6
7
8
    public void ImageUp(){ // 이미지 갱신
        
        Intent intent2 = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri memofile = Uri.fromFile(f);
        intent2.setData(memofile);
        sendBroadcast(intent2);
    }
    
cs
이미지 갱신의 코드이다 방송이라는 기법이 들어가있는데 Intent로 파일 미디어 스캐닝을 실행하고Intent에 파일의 Uri를 저장해준다. 
여기서 쓰인 f 변수는 mPath의 주소를 File로 변경한 것이다.
그리고 파일에서 다시 Uri로 변경하여 Uri객체로 받아온다.
그리고ㅓ setData로 인텐트에 데이터를 저장해준뒤 
sendBroadcast로 방송을 해준다.
이렇게하면 갤러리에 바로바로 갱신이 된다.

그리고 갤러리 코드에서는 DB에 저장하기위한 갤러리 사진파일의 절대경로를 String 으로 받아와서 저장해야하는데 그에따른 함수를 다른 사이트에서 코드를 퍼와서 저장하였다.
data.getData 로 현재 갤러리에서 선택한 파일을 받아온다 Uri로 저장이 되는데 Uri에서다시 절대주소로 String값을 출력해주는 함수를 보자.
1
2
3
4
5
6
7
8
    public String getRealPathFromURI(Uri contentUri){
        String [] proj={MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery( contentUri, proj, nullnullnull); 
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
        
    }
cs


이렇게 구성된 함수이다.

그리고나서 확인 키를 누르게되면 이렇게 잘 저장이 될것이다.



하지만 만약 사진파일이 없을때는 리스트뷰에 올리고싶다면 을 하고싶다면 커스텀리스트뷰에 2가지의 레이아웃을 추가하면된다.

저번에 만든 커스텀 리스트뷰에서 약간만 수정을 하면된다.
만약 이미지파일이 없다면 null 이 넘겨져 올것이므로 null과 비교한다.
수정된 후코드이다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.example.memoproz;
 
import java.util.*;
 
import android.annotation.SuppressLint;
import android.content.*;
import android.graphics.*;
import android.view.*;
import android.widget.*;
 
@SuppressLint("ViewHolder")
public class CustomAdapter extends BaseAdapter{
    public Context context; // 컨텍스트 저장
    ArrayList<GetSet> MemoList; // 아이템 리스트
    public LayoutInflater inflater;
    
    public CustomAdapter(Context context, ArrayList<GetSet> MemoList){ //  생성자 생성
        
        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.MemoList = MemoList;
        
    } 
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return MemoList.size();
    }
 
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return MemoList.get(position);
    }
 
    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) { // 가장중요한 곳 여기서 뷰생성
        
        int row= 0;
        if(convertView == null){
            if(MemoList.get(position).getImageName().equals("null")){
                row = R.layout.customview2;
            }else{
                row = R.layout.customview;
            }
 
        }
        
        convertView = inflater.inflate(row, parent, false);
        if(MemoList.get(position).getImageName().equals("null")){
            
            TextView CustomMemoName = (TextView)convertView.findViewById(R.id.CustomName2);
            TextView CustomMemoMemo = (TextView)convertView.findViewById(R.id.CustomMemo2);
            TextView CustomMemoDay = (TextView)convertView.findViewById(R.id.CustomDay2);
 
            CustomMemoName.setText(MemoList.get(position).getName()); // 제목연결
            CustomMemoMemo.setText(MemoList.get(position).getMemo()); // 메모연결
            CustomMemoDay.setText(MemoList.get(position).getDay()); // 이름연결    
            
        }else{
            ImageView CustomMemoImg = (ImageView)convertView.findViewById(R.id.CustomImg);
            TextView CustomMemoName = (TextView)convertView.findViewById(R.id.CustomName);
            TextView CustomMemoMemo = (TextView)convertView.findViewById(R.id.CustomMemo);
            TextView CustomMemoDay = (TextView)convertView.findViewById(R.id.CustomDay);
            
            CustomMemoImg.setImageBitmap(BitmapFactory.decodeFile(MemoList.get(position).getImageName()));
            CustomMemoName.setText(MemoList.get(position).getName()); // 제목연결
            CustomMemoMemo.setText(MemoList.get(position).getMemo()); // 메모연결
            CustomMemoDay.setText(MemoList.get(position).getDay()); // 이름연결            
        }
 
        
        
        
        
        return convertView; // 뷰리턴
        
    }
 
}
 
cs
밑에서 if문으로 equals 메소드로 비교하여서 image의 스트링이 null이라면

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
32
33
34
35
36
37
 
<?xml version="1.0" encoding="utf-8"?>
<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" >
 
 
    <TextView
        android:id="@+id/CustomName2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/CustomImg"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
 
    <TextView
        android:id="@+id/CustomDay2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="test"
        android:textAppearance="?android:attr/textAppearanceSmall" />
 
    <TextView
        android:id="@+id/CustomMemo2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/CustomName2"
        android:text="Small Text"
        android:textAppearance="?android:attr/textAppearanceSmall" />
 
</RelativeLayout>
 
cs


이레이아웃을

null이 아니라면

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 
<?xml version="1.0" encoding="utf-8"?>
<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" >
 
    <ImageView
        android:id="@+id/CustomImg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:padding="2sp"
        
        android:maxHeight="50sp"
        android:maxWidth="70sp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        
        android:src="@drawable/ic_launcher" />
 
    <TextView
        android:id="@+id/CustomName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/CustomImg"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
 
    <TextView
        android:id="@+id/CustomDay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="test"
        android:textAppearance="?android:attr/textAppearanceSmall" />
 
    <TextView
        android:id="@+id/CustomMemo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/CustomImg"
        android:layout_alignLeft="@+id/CustomName"
        android:text="Small Text"
        android:textAppearance="?android:attr/textAppearanceSmall" />
 
</RelativeLayout>
 
cs



이레이아웃을 반환할 것이다. 이제 수정된 코드의 레이아웃을 보게되면


이런식으로 잘 나타나게 되는것을 볼수 있다.

다음시간엔 커스텀 리스트뷰의 클릭리스너 롱클릭리스너를 알아보도록하겠다.




728x90