RiverMoon Tech Blog
  • 안드로이드 프로그래밍 과제(Java) - 이미지뷰어와 필터
    2023년 11월 17일 21시 56분 20초에 업로드 된 글입니다.
    작성자: Moonsu99

    환경

    • OS - Mac OS 13.5.2
    • Tools - Android Studio Iguana | 2023.2.1 Canary 5
    • Language - Java
    • android version - 12
    • tartgetSDK - 33
    • minSDK - 28

     

    조건

    1. 버튼 사이에 현재 그림 번호/전체 그림 개수 TextView가 표시된다.

    2. 첫 번째 그림에서 이전 그림을 선택하면 마지막 그림이 나오고, 마지막 그림에서 다음 그림을 선택하면 첫 번째 그림이 나온다.

    3. 상단에 String을 입력하는 EditText와 필터 적용Button이 표시되는데, 이 Button을 누르면 입력된 String이 파일명에 포함된 그림들만 표시된다. 

    4. /sdcard/Pictures에는 그림1과 같이 test1~3 renoir01~03 등 총 6개의 그림 파일이 있다. 앱을 실행하면 그림2와 같이 여섯 개의 그림 파일이 확인되어 1/6으로 표시되고 첫 번째 그림이 나타난다.

    5. "이전 그림"을 클릭하면 마지막 그림으로 바뀌고 6/6으로 표시된다.

    6. 그림3과 같이 “renoir”를 입력하고 필터 적용 버튼을 누르면 “renoir”가 파일명에 포함된 3개의 그림 목록으로 변경되어 첫 번째  그림이 나타나고 1/3으로 표시된다.

     

    힌트 : FileFilter를 사용할 때 파일명에 대해 contains()와 같은 String Method를 사용하면 특정한 문자열을 포함한 파일만을 가려 낼 수 있다.

     

     

    순서대로 그림 1,2,3

     

     

    풀이

     

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <EditText
                android:id="@+id/EditText_FilterString"
                android:layout_weight="3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:hint="필터 스트링"/>
            <Button
                android:id="@+id/Button_FilterApply"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="필터 적용"/>
        </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                    <Button
                        android:id="@+id/Button_PreviousPicture"
                        android:layout_weight="3"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:text="이전 그림"/>
                <TextView
                    android:id="@+id/TextView_PictureIndicator"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="1/6"
                    android:layout_weight="1"/>
    
                <Button
                    android:id="@+id/Button_NextPicture"
                    android:layout_weight="3"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:text="다음 그림"/>
            </LinearLayout>
        <com.example.knu_mobilework5.MyPictureView
            android:id="@+id/myPictureView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

     

     

     

    MyPictureView.java

    public class MyPictureView extends View {
        String imagePath = null;
    
        public MyPictureView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (imagePath != null) {
                Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
                canvas.drawBitmap(bitmap, 0, 0, null);
                bitmap.recycle();
            }
        }
    }

     

     

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
        Button btnPrev, btnNext, buttonFilterApply;
        MyPictureView myPicture;
        EditText editTextFilterString;
        int curNum;
        File[] imageFiles;
        String imageFname;
        TextView tvNumber;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            setTitle("필터 이미지 뷰어");
            ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.WRITE_EXTERNAL_STORAGE},MODE_PRIVATE);
    
            btnPrev = findViewById(R.id.Button_PreviousPicture);
            btnNext = findViewById(R.id.Button_NextPicture);
            myPicture = findViewById(R.id.myPictureView1);
            tvNumber = findViewById(R.id.TextView_PictureIndicator);
            editTextFilterString = findViewById(R.id.EditText_FilterString);
            buttonFilterApply = findViewById(R.id.Button_FilterApply);
    
            loadInitialImages();
    
            btnPrev.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    if (curNum <= 0) {
                        curNum = imageFiles.length - 1;
                    } else {
                        curNum--;
                    }
                    updateImage();
                }
            });
    
            btnNext.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    if (curNum >= imageFiles.length - 1) {
                        curNum = 0;
                    } else {
                        curNum++;
                    }
                    updateImage();
                }
            });
    
            buttonFilterApply.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String filter = editTextFilterString.getText().toString();
                    filterImages(filter);
                }
            });
        }
    
        private void loadInitialImages() {
            imageFiles = new File(Environment.getExternalStorageDirectory()
                    .getAbsolutePath()+"/Pictures").listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return !file.getName().startsWith(".");
                }
            });
    
            if (imageFiles != null && imageFiles.length > 0) {
                curNum = 0;
                updateImage();
            } else {
                tvNumber.setText("No images available");
            }
        }
    
        private void updateImage() {
            if (imageFiles != null && imageFiles.length > 0) {
                imageFname = imageFiles[curNum].toString();
                myPicture.imagePath = imageFname;
                myPicture.invalidate();
                tvNumber.setText((curNum + 1) + "/" + imageFiles.length);
            }
        }
    
        private void filterImages(String filter) {
            File directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures");
            File[] filteredFiles = directory.listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return file.getName().contains(filter) && !file.getName().startsWith(".");
                }
            });
    
            if (filteredFiles != null && filteredFiles.length > 0) {
                imageFiles = filteredFiles;
                curNum = 0;
                updateImage();
            } else {
                Toast.makeText(MainActivity.this, "No matching images found", Toast.LENGTH_SHORT).show();
            }
        }
    }

     

    댓글