Custom Gallery를 동작하도록 만들기는 했지만 scroll을 상하로 바꿔서 격자 구조로 사진의 thumbnail을 보는 게 편할 것 같다. 찾아보니 GridView라는 layout이 따로 있었다. Android API reference에 따르면 애초에 Grid View 자체가 2차원으로 item을 보여주는(이 말은 즉, Main이 되는 View위에 다른 View를 여러 개 보여주는) scroll이 가능한 Viewgroup이라고 한다. 이전에 만들었던 앱에서 Gallery를 GridView로 바꾸어 구연해 보자. 

1. 목적 : GridView에 대해 알아보고 이를 이용한 Image Gallery(List)를 만들어보자

2. 개발 환경
 - PC : Windows 7, Android Studio 1.4.1(64-bit)
 - Phone : LG G pro Lollipop(API 21)

3. 참고자료
 1) Android Developers - Grid View Example (http://developer.android.com/intl/ko/guide/topics/ui/layout/gridview.html)
 2) AndroidHive - Android GridView Layout Tutorial (http://www.androidhive.info/2012/02/android-gridview-layout-tutorial/)

4. 과정
 1) Main이 되는 Layout(여기서는 activity_main.xml)에 <GridView ...></GridView>를 다음과 같이 선언한다. 자동 완성 scroll 밑으로 <GridLayout>도 볼 수 있으나 minSdkVersion이 높으므로 낮은 사양에서도 사용할 수 있도록 <GridView>를 사용하기로 한다.

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
    android:columnWidth="90dp" <!-- columnWidth(나눠진 칸 안에 있는 View의 가로 길이)에 따라 column(열)의 갯수가 달라진다 -->
    android:numColumns="auto_fit" <!-- 임의로 숫자 지정 가능 -->
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center">

</GridView>

 

 2) GridView 내부에 ImageView 들을 뿌릴 Adapter를 다음과 같이 정의한다. 이전의 Adapter 부분과 비슷하다.

    // 이상 생략
   
// create a new ImageView for each item referenced by the Adapter
   // 참고자료 내 Android Developers에 게시된 Example 수정

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {
            // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
        } else {
            imageView = (ImageView) convertView;
        }
        bm = BitmapFactory.decodeFile(mBasePath + File.separator + mImgList[position]);
        Bitmap mThumbnail = ThumbnailUtils.extractThumbnail(bm, 300, 300);
        imageView.setPadding(8, 8, 8, 8);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.MATCH_PARENT, GridView.LayoutParams.MATCH_PARENT));
        imageView.setImageBitmap(mThumbnail);
        return imageView;
    }
    // 이하 생략

 

 3) MainActivity.java 에서 앞서 정의한 GridView layout과 Adapter를 연결하고 Item Click 시 adapter에서 넘어온 해당 ImageView의 주소 값을 Toast message로 보여주도록 다음과 같이 설정한다.


public class
MainActivity extends AppCompatActivity {

    public String basePath = null;
    public GridView mGridView;
    public CustomImageAdapter mCustomImageAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "MyCameraApp");

        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                Log.d("MyCameraApp", "failed to create directory");
            }
        }

        basePath = mediaStorageDir.getPath();

        mGridView = (GridView)findViewById(R.id.gridview); // .xml의 GridView와 연결
        mCustomImageAdapter = new CustomImageAdapter(this, basePath); // 앞에서 정의한 Custom Image Adapter와 연결
        mGridView.setAdapter(mCustomImageAdapter); // GridView가 Custom Image Adapter에서 받은 값을 뿌릴 수 있도록 연결
        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getApplicationContext(), mCustomImageAdapter.getItemPath(position), Toast.LENGTH_LONG).show();
            }
        });
    }
}

 

(위 Code의 실행 결과)

  

      

 

  앞의 예시가 기본 AlertDialog의 Method를 사용한 경우라면 이번에는 이전의 ListView와 같이 LayoutInflater를 활용하여 Custom Layout을 AlertDialog에 입혀서 활용해 보자. 실제 App. 개발시에 중요한 부분은 아니겠지만 이왕이면 여러가지 사용법을 알면 좋지 않을까 싶다.

1. 목적 : Custom Layout을 LayoutInflater를 통해 AlertDialog에 반영해 알림창을 만들어 보자.

2. 개발 환경
 - PC : Windows 7, Android Studio 1.4.1(64-bit)
 - Phone : LG G pro Lollipop(API 21)

3. 참고자료
 1) Android Developers - AlertDialog Reference (http://developer.android.com/reference/android/app/AlertDialog.html)
 2) 창조적 고찰 - Android 커스텀 다이얼로그 생성 (http://ismydream.tistory.com/107)

4. 과정
  이전의 'AlertDialog를 활용한 알림창 띄우기 01 - 기본'편에 살을 덧붙여 만들어 봤다.

 1) AlertDialog가 받아들일 Custom View에 해당하는 layout 파일을 /layout directory 밑에 생성한다.

<!-- /layout/custom_alert_layout.xml -->
<?
xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="30dp">

    <ImageView
        android:id="@+id/customdialogicon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>
    <TextView
        android:id="@+id/customtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/customdialogicon"
        android:padding="10dp"
        android:text="Hello World!"/>
</RelativeLayout>

 

 2) AlertDialog를 띄울 activity에 LayoutInflater를 통해 위의 layout file을 연결시키고, 해당 사항을 AlertDialog.Builder의 setView(View view)을 통해 반영한다.

public class MainActivity extends AppCompatActivity {

    public ImageButton imgBtn;
    public TextView returnVal;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imgBtn = (ImageButton)findViewById(R.id.imgbtn); // ImageButton의 activity 내 생성 및 연결
        returnVal = (TextView)findViewById(R.id.returnval);
        imgBtn.setOnClickListener(new View.OnClickListener() { // ImageButton을 Click시 AlertDialog가 생성되도록 아래과 같이 설계
            @Override
            public void onClick(View v) {
                // LayoutInflater를 통해 위의 custom layout을 AlertDialog에 반영. 이 외에는 거의 동일하다.
                LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
                View view = inflater.inflate(R.layout.custom_alert_layout, null);
                TextView customTitle = (TextView)view.findViewById(R.id.customtitle);
                customTitle.setText("종료하시겠습니까?");
                customTitle.setTextColor(Color.BLACK);
                ImageView customIcon = (ImageView)view.findViewById(R.id.customdialogicon);
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setView(view);
                builder.setPositiveButton("네", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                });
                builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        returnVal.setText("Custom AlertDialog를 통해서 return");
                        dialog.dismiss();
                    }
                });
                AlertDialog dialog = builder.create();
                dialog.show();

            }
        });
    }
}

(위 code의 실행 결과)

  

  

 

+ Recent posts