Study/Android

CheckBox & 갤러리 사진 선택

Kostrian 2015. 1. 29. 11:25

갤러리 사진 선택


갤러리에서 사진을 가져올땐 인텐트를 사용해야 한다. 다만 새로운 엑티비티를 만들어서 인텐트를 생성하는게 아니라 안드로이드 자체 내에 있는걸 사용한다.

1
2
3
4
5
6
7
Intent intent = new Intent(Intent.ACTION_PICK, MedaStore.Images.Media.EXTERNAL_CONNECT_URI);
intent.setType("image/*");
//Crop 기능 활성화
intent.putExtra("crop""true");
intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
intent.putExtra("outputFormat", Bitmap.compressFormat.JPEG.toString());
startActivityForResult(intent, GET_PICTURE_URI);
cs


이렇게 생성한 후 다시 엑티비티를 넘길 때는 Bitmap객체를 넘길수가 없다. 이를 해결하기 위한 방법으로 임시파일 생성이 있다. 이에대한 방법은 http://warmz.tistory.com/400 에 자세하게 나와있다.


위의 코드에서 이미지를 가져오고 나서 


1
2
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
imageView.setImageBitmap(bitmap);
cs

을 하게 된다면 manifest를 건들인적이 없다면 계속해서 bitmap에 null이 들어가 있다. 이때 로그캣을 잘 보면 Permission Denied가 떠있는걸 볼수 있다. 때문에 어플리케이션에서 안드로이드에 권한을 요청해야 된다. 이는 menifest에 한줄만 추가하면 해결된다.


1
2
3
4
    ...
    </application>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
cs


이제 퍼미션까지 부여해주었으니 Bitmap객체의 생성이 가능하다.


CheckBox


주소록​을 만들면서 체크박스를 통해 동시선택을 해서 일괄적으로 삭제해주어야 할 필요가 생겼다. 이를 위해 listview_item.xml에 체크박스를 추가해 주었다.

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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout    
xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_height="match_parent"    
android:layout_width="match_parent"    android:orientation="vertical">
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <LinearLayout
            android:id="@+id/llMain"
            android:layout_width="match_parent" android:layout_height="wrap_content"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/itemImage"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:src="@drawable/ic_launcher"/>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <TextView
                    android:id="@+id/name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="Text1"/>
                <TextView
                    android:id="@+id/phone"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Text2"/>
            </LinearLayout>
        </LinearLayout>
        <CheckBox
            android:id="@+id/multiCheck"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_alignRight="@id/llMain"
            android:visibility="gone"/>
    </RelativeLayout>
    <LinearLayout
        android:id="@+id/buttonLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
            <Button
                android:id="@+id/btnModi"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:text="Modify"/>
            <Button
                android:id="@+id/btnDel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:text="Delete"/>
        </LinearLayout>
</LinearLayout>
cs


다음엔 메인 레이아웃에 체크된 리스트를 삭제하기 위한 버튼을 삽입하고 visibility를 gone으로 해놓은 다음 자바 코드에서 필요시에 보여주도록 한다. MainActivity.java에 이를 처리하기 위한 코드를 삽입하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    ...
        case R.id.action_check :
            if ( adapter.checkBoxFlag ) {
                // 어뎁터에서 체크박스를 보여줄지 말지를 결정.  turnOffCheckBox는 checkBox를 끄도록 만들면 된다.
                adapter.turnOffCheckBox();
                // 체크박스가 활성화 되어 있을때 버튼이 다시 한번 눌렸을경우 삭제버튼 없앰
                checkedDelBtn.setVisibility(Button.GONE);
                adapter.dataChange();
            }
            else {
                adapter.turnOnCheckBox();
                checkedDelBtn.setVisibility(Button.VISIBLE);
                adapter.dataChange();
            }
            break;
    }
}
 
cs



그리고 리스트뷰의 아이템에 boolean isChecked를 넣은다음 체크박스가 체크 될때마다 이를 갱신해 준다. 어뎁터의 getView에 코드를 넣으면 된다.


1
2
3
4
5
6
7
8
9
10
if ( viewHolder.checkBox != null ) {
    viewHolder.checkBox.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // 체크 상태를 계속 확인해서 상태가 변경된다면 리스트뷰 아이템도 갱신하여 준다.
            listData.isChecked = isChecked;
        }
    });
}
 
cs


이제 위에서 각각 아이템의 상태를 넣어주었으니 이제 체크가 되어 있으면 지워주면 된다.

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
case R.id.checkedDelBtn :
    // 체크되어 있는 아이템의 위치를 저장하기 위한 배열
    int[] positions = new int[adapter.getCount()];
    // 처음부터 체우기 위한 변수
    int index = 0;
 
    for ( int i = 0; i < adapter.getCount(); ++i ) {
        if ( ((ListData)adapter.getItem(i)).isChecked )
            // 체크가 되어 있다면 배열에 처음부터 저장하고 index값을 1씩 증가 시킨다.
            positions[index++] = i;
    }
 
    // 실제 배열에 들어있는 데이터의 갯수와 같기 때문에 인덱스로 쓰기 위해서는 1만큼 빼서 사용한다.
    // 이때 앞에 있는 아이템부터 삭제를 시작한다면 ArrayList특성상 하나씩 다시 밀리기 때문에 지우고자 하는 아이템의 
    // 위치가 틀려진다. 
    for ( int i = index - 1; i >= 0; --i ) {
        // 어뎁터에서 체크된 위치의 아이템을 하나씩 가져온다.
        ListData temp = (ListData)adapter.getItem(positions[i]);
        // 쿼리문에 사용할 데이터를 지우기전 미리 저장
        String[] datas = {temp.imagePath, temp.name, temp.phone};
        // 체크된 아이템 삭제
        adapter.remove(positions[i])
        // 쿼리문 작성후 쿼리 전송
        query = String.format("DELETE FROM list WHERE imagePath='%s' and name='%s' and phone='%s';", datas[0],datas[1], datas[2]);
        db.execSQL(query);
    }
    // 삭제를 하였으니 삭제버튼을 다시 감춘다.
    checkedDelBtn.setVisibility(Button.GONE);
    // 또한 체크박스를 다시 감춘다.
    adapter.turnOffCheckBox();
    adapter.dataChange();
    break;
 
cs


'Study > Android' 카테고리의 다른 글

DB에서 데이터를 가져와서 게시판 읽는 어플 제작  (0) 2015.01.29
MYSQL에서 안드로이드로 데이터 가져오기  (0) 2015.01.29
Intent & SQLite  (0) 2015.01.29
Custom ListView  (0) 2015.01.29
Simple ListView  (0) 2015.01.29