diff --git a/app/build.gradle b/app/build.gradle index b3a5152..cc8b112 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,10 +17,20 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + + buildFeatures { + viewBinding true + } } dependencies { implementation 'androidx.appcompat:appcompat:1.0.0' implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.viewpager:viewpager:1.0.0' + implementation 'com.github.bumptech.glide:glide:4.12.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 63a620e..bd6fbab 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="cc.winboll.gallery"> + + + + + + + + + diff --git a/app/src/main/java/cc/winboll/gallery/Album.java b/app/src/main/java/cc/winboll/gallery/Album.java new file mode 100644 index 0000000..f4a51f4 --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/Album.java @@ -0,0 +1,22 @@ +package cc.winboll.gallery; + +import android.net.Uri; + +public class Album { + private String name; + private String path; + private Uri coverUri; + private int imageCount; + + public Album(String name, String path, Uri coverUri, int imageCount) { + this.name = name; + this.path = path; + this.coverUri = coverUri; + this.imageCount = imageCount; + } + + public String getName() { return name; } + public String getPath() { return path; } + public Uri getCoverUri() { return coverUri; } + public int getImageCount() { return imageCount; } +} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/AlbumActivity.java b/app/src/main/java/cc/winboll/gallery/AlbumActivity.java new file mode 100644 index 0000000..49c87b6 --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/AlbumActivity.java @@ -0,0 +1,131 @@ +package cc.winboll.gallery; + +import android.content.ContentResolver; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import java.util.ArrayList; + +public class AlbumActivity extends AppCompatActivity { + private static final int PERMISSION_REQUEST_CODE = 101; + public static final String EXTRA_ALBUM_PATH = "album_path"; + public static final String EXTRA_ALBUM_NAME = "album_name"; + private RecyclerView recyclerView; + private ImageAdapter adapter; + private String albumPath; + private String albumName; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + albumPath = getIntent().getStringExtra(EXTRA_ALBUM_PATH); + albumName = getIntent().getStringExtra(EXTRA_ALBUM_NAME); + + getSupportActionBar().setTitle(albumName); + + recyclerView = findViewById(R.id.recycler_view); + recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); + adapter = new ImageAdapter(); + recyclerView.setAdapter(adapter); + + adapter.setOnImageClickListener((position, urls) -> { + Intent intent = new Intent(this, ImageViewerActivity.class); + intent.putParcelableArrayListExtra(ImageViewerActivity.EXTRA_IMAGE_URLS, urls); + intent.putExtra(ImageViewerActivity.EXTRA_POSITION, position); + startActivity(intent); + }); + + if (checkPermission()) { + loadImages(); + } else { + requestPermission(); + } + } + + private boolean checkPermission() { + return ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) + == PackageManager.PERMISSION_GRANTED; + } + + private void requestPermission() { + ActivityCompat.requestPermissions(this, + new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_CODE); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == PERMISSION_REQUEST_CODE) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + loadImages(); + } else { + Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show(); + } + } + } + + private void loadImages() { + ArrayList imageUrls = new ArrayList<>(); + ContentResolver contentResolver = getContentResolver(); + Uri collection = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + + String selection = android.provider.MediaStore.Images.Media.DATA + " LIKE ?"; + String[] selectionArgs = new String[]{albumPath + "%"}; + String sortOrder = android.provider.MediaStore.Images.Media.DATE_ADDED + " DESC"; + + try (Cursor cursor = contentResolver.query(collection, null, selection, selectionArgs, sortOrder)) { + if (cursor != null) { + int dataColumn = cursor.getColumnIndexOrThrow(android.provider.MediaStore.Images.Media.DATA); + while (cursor.moveToNext()) { + String path = cursor.getString(dataColumn); + if (path != null && path.startsWith(albumPath + "/")) { + long id = cursor.getLong(cursor.getColumnIndexOrThrow(android.provider.MediaStore.Images.Media._ID)); + Uri contentUri = Uri.withAppendedPath(collection, String.valueOf(id)); + imageUrls.add(contentUri); + } + } + } + } + + if (imageUrls.isEmpty()) { + Toast.makeText(this, R.string.no_images_found, Toast.LENGTH_SHORT).show(); + } + adapter.setData(imageUrls); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_refresh) { + if (checkPermission()) { + loadImages(); + } + return true; + } + return super.onOptionsItemSelected(item); + } +} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/AlbumAdapter.java b/app/src/main/java/cc/winboll/gallery/AlbumAdapter.java new file mode 100644 index 0000000..56c7e74 --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/AlbumAdapter.java @@ -0,0 +1,71 @@ +package cc.winboll.gallery; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import java.util.ArrayList; + +public class AlbumAdapter extends RecyclerView.Adapter { + private ArrayList albums = new ArrayList<>(); + private OnAlbumClickListener listener; + + public interface OnAlbumClickListener { + void onAlbumClick(Album album); + } + + public void setOnAlbumClickListener(OnAlbumClickListener listener) { + this.listener = listener; + } + + public void setData(ArrayList albums) { + this.albums = albums; + notifyDataSetChanged(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_album, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + Album album = albums.get(position); + Glide.with(holder.coverImage.getContext()) + .load(album.getCoverUri()) + .centerCrop() + .into(holder.coverImage); + holder.albumName.setText(album.getName()); + holder.imageCount.setText(album.getImageCount() + " photos"); + + holder.itemView.setOnClickListener(v -> { + if (listener != null) { + listener.onAlbumClick(album); + } + }); + } + + @Override + public int getItemCount() { + return albums.size(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + ImageView coverImage; + TextView albumName; + TextView imageCount; + ViewHolder(View itemView) { + super(itemView); + coverImage = itemView.findViewById(R.id.album_cover); + albumName = itemView.findViewById(R.id.album_name); + imageCount = itemView.findViewById(R.id.image_count); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/ImageAdapter.java b/app/src/main/java/cc/winboll/gallery/ImageAdapter.java new file mode 100644 index 0000000..ff39fa7 --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/ImageAdapter.java @@ -0,0 +1,65 @@ +package cc.winboll.gallery; + +import android.content.Intent; +import android.net.Uri; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import java.util.ArrayList; + +public class ImageAdapter extends RecyclerView.Adapter { + private ArrayList imageUrls = new ArrayList<>(); + private OnImageClickListener listener; + + public interface OnImageClickListener { + void onImageClick(int position, ArrayList urls); + } + + public void setOnImageClickListener(OnImageClickListener listener) { + this.listener = listener; + } + + public void setData(ArrayList urls) { + this.imageUrls = urls; + notifyDataSetChanged(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_gallery, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + Glide.with(holder.imageView.getContext()) + .load(imageUrls.get(position)) + .centerCrop() + .into(holder.imageView); + + holder.imageView.setOnClickListener(v -> { + if (listener != null) { + listener.onImageClick(position, imageUrls); + } + }); + } + + @Override + public int getItemCount() { + return imageUrls.size(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + ImageView imageView; + ViewHolder(View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.image); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/ImagePagerAdapter.java b/app/src/main/java/cc/winboll/gallery/ImagePagerAdapter.java new file mode 100644 index 0000000..047ed97 --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/ImagePagerAdapter.java @@ -0,0 +1,52 @@ +package cc.winboll.gallery; + +import android.net.Uri; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import androidx.annotation.NonNull; +import androidx.viewpager.widget.PagerAdapter; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import java.util.ArrayList; + +public class ImagePagerAdapter extends PagerAdapter { + private ArrayList imageUrls; + + public ImagePagerAdapter(ArrayList imageUrls) { + this.imageUrls = imageUrls; + } + + @Override + public int getCount() { + return imageUrls.size(); + } + + @NonNull + @Override + public Object instantiateItem(@NonNull ViewGroup container, int position) { + View view = LayoutInflater.from(container.getContext()) + .inflate(R.layout.item_image_pager, container, false); + ImageView imageView = view.findViewById(R.id.image); + + Glide.with(imageView.getContext()) + .load(imageUrls.get(position)) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .skipMemoryCache(true) + .into(imageView); + + container.addView(view); + return view; + } + + @Override + public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { + container.removeView((View) object); + } + + @Override + public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { + return view == object; + } +} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/ImageViewerActivity.java b/app/src/main/java/cc/winboll/gallery/ImageViewerActivity.java new file mode 100644 index 0000000..39fee1f --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/ImageViewerActivity.java @@ -0,0 +1,73 @@ +package cc.winboll.gallery; + +import android.app.Activity; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageButton; +import androidx.viewpager.widget.ViewPager; +import java.util.ArrayList; + +public class ImageViewerActivity extends Activity implements ViewPager.OnPageChangeListener { + public static final String EXTRA_IMAGE_URLS = "image_urls"; + public static final String EXTRA_POSITION = "position"; + + private ArrayList imageUrls; + private int currentPosition; + private ViewPager viewPager; + private View toolbar; + private ImageButton btnBack; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + setContentView(R.layout.activity_image_viewer); + + imageUrls = getIntent().getParcelableArrayListExtra(EXTRA_IMAGE_URLS); + currentPosition = getIntent().getIntExtra(EXTRA_POSITION, 0); + + viewPager = findViewById(R.id.view_pager); + toolbar = findViewById(R.id.toolbar); + btnBack = findViewById(R.id.btn_back); + + ImagePagerAdapter adapter = new ImagePagerAdapter(imageUrls); + viewPager.setAdapter(adapter); + viewPager.setCurrentItem(currentPosition); + viewPager.addOnPageChangeListener(this); + + btnBack.setOnClickListener(v -> finish()); + + viewPager.setOnClickListener(v -> toggleToolbar()); + } + + private void toggleToolbar() { + if (toolbar.getVisibility() == View.VISIBLE) { + toolbar.setVisibility(View.GONE); + } else { + toolbar.setVisibility(View.VISIBLE); + } + } + + @Override + public void onPageSelected(int position) { + currentPosition = position; + } + + @Override + public void onPageScrollStateChanged(int state) {} + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} + + @Override + public void onBackPressed() { + if (viewPager.getCurrentItem() > 0) { + viewPager.setCurrentItem(viewPager.getCurrentItem() - 1); + } else { + super.onBackPressed(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/MainActivity.java b/app/src/main/java/cc/winboll/gallery/MainActivity.java index 6a3e996..bf51ae1 100644 --- a/app/src/main/java/cc/winboll/gallery/MainActivity.java +++ b/app/src/main/java/cc/winboll/gallery/MainActivity.java @@ -1,19 +1,169 @@ package cc.winboll.gallery; +import android.Manifest; +import android.content.ContentResolver; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import java.io.File; +import java.util.ArrayList; public class MainActivity extends AppCompatActivity { - + private static final int PERMISSION_REQUEST_CODE = 100; + private RecyclerView recyclerView; + private AlbumAdapter adapter; + private Preferences prefs; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - - Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar); - setSupportActionBar(toolbar); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + prefs = new Preferences(this); + + recyclerView = findViewById(R.id.recycler_view); + recyclerView.setLayoutManager(new GridLayoutManager(this, 2)); + adapter = new AlbumAdapter(); + recyclerView.setAdapter(adapter); + + adapter.setOnAlbumClickListener(album -> { + Intent intent = new Intent(this, AlbumActivity.class); + intent.putExtra(AlbumActivity.EXTRA_ALBUM_PATH, album.getPath()); + intent.putExtra(AlbumActivity.EXTRA_ALBUM_NAME, album.getName()); + startActivity(intent); + }); + + if (checkPermission()) { + loadAlbums(); + } else { + requestPermission(); + } + } + + private boolean checkPermission() { + return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) + == PackageManager.PERMISSION_GRANTED; + } + + private void requestPermission() { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_CODE); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == PERMISSION_REQUEST_CODE) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + loadAlbums(); + } else { + Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show(); + } + } + } + + private void loadAlbums() { + String folderPath = prefs.getFolderPath(); + File baseFolder = new File(folderPath); + + if (!baseFolder.exists() || !baseFolder.isDirectory()) { + folderPath = Environment.getExternalStorageDirectory() + "/DCIM"; + baseFolder = new File(folderPath); + if (!baseFolder.exists()) { + folderPath = Environment.getExternalStorageDirectory() + "/Pictures"; + baseFolder = new File(folderPath); + } + } + + ArrayList albums = new ArrayList<>(); + + File[] subfolders = baseFolder.listFiles(File::isDirectory); + if (subfolders != null) { + for (File subfolder : subfolders) { + ArrayList images = getImagesInFolder(subfolder.getAbsolutePath()); + if (!images.isEmpty()) { + Uri latestImage = images.get(0); + albums.add(new Album(subfolder.getName(), subfolder.getAbsolutePath(), latestImage, images.size())); + } + } + } + + if (albums.isEmpty()) { + Toast.makeText(this, R.string.no_images_found, Toast.LENGTH_SHORT).show(); + } + adapter.setData(albums); + } + + private ArrayList getImagesInFolder(String folderPath) { + ArrayList imageUrls = new ArrayList<>(); + ContentResolver contentResolver = getContentResolver(); + Uri collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + + String selection = MediaStore.Images.Media.DATA + " LIKE ?"; + String[] selectionArgs = new String[]{folderPath + "/%"}; + String sortOrder = MediaStore.Images.Media.DATE_ADDED + " DESC"; + + try (Cursor cursor = contentResolver.query(collection, null, selection, selectionArgs, sortOrder)) { + if (cursor != null) { + int dataColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + while (cursor.moveToNext()) { + String path = cursor.getString(dataColumn); + if (path != null) { + long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)); + Uri contentUri = Uri.withAppendedPath(collection, String.valueOf(id)); + imageUrls.add(contentUri); + } + } + } + } + return imageUrls; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int id = item.getItemId(); + if (id == R.id.action_settings) { + startActivity(new Intent(this, SettingsActivity.class)); + return true; + } else if (id == R.id.action_refresh) { + if (checkPermission()) { + loadAlbums(); + } + return true; + } + return super.onOptionsItemSelected(item); } + @Override + protected void onResume() { + super.onResume(); + if (checkPermission()) { + loadAlbums(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/Preferences.java b/app/src/main/java/cc/winboll/gallery/Preferences.java new file mode 100644 index 0000000..f9ce948 --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/Preferences.java @@ -0,0 +1,28 @@ +package cc.winboll.gallery; + +import android.content.Context; +import android.content.SharedPreferences; + +public class Preferences { + private static final String PREF_NAME = "gallery_prefs"; + private static final String KEY_FOLDER_PATH = "folder_path"; + private static final String DEFAULT_PATH = "/storage/emulated/0/DCIM"; + + public static String getDefaultPath() { + return DEFAULT_PATH; + } + + private final SharedPreferences prefs; + + public Preferences(Context context) { + prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); + } + + public String getFolderPath() { + return prefs.getString(KEY_FOLDER_PATH, DEFAULT_PATH); + } + + public void setFolderPath(String path) { + prefs.edit().putString(KEY_FOLDER_PATH, path).apply(); + } +} \ No newline at end of file diff --git a/app/src/main/java/cc/winboll/gallery/SettingsActivity.java b/app/src/main/java/cc/winboll/gallery/SettingsActivity.java new file mode 100644 index 0000000..bd94ddd --- /dev/null +++ b/app/src/main/java/cc/winboll/gallery/SettingsActivity.java @@ -0,0 +1,38 @@ +package cc.winboll.gallery; + +import android.os.Bundle; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; + +public class SettingsActivity extends AppCompatActivity { + private Preferences prefs; + private EditText editFolderPath; + private TextView textCurrentPath; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings); + + prefs = new Preferences(this); + + editFolderPath = findViewById(R.id.edit_folder_path); + textCurrentPath = findViewById(R.id.text_current_path); + Button btnSave = findViewById(R.id.btn_save); + + String currentPath = prefs.getFolderPath(); + editFolderPath.setText(currentPath); + textCurrentPath.setText("Current: " + currentPath); + + btnSave.setOnClickListener(v -> { + String newPath = editFolderPath.getText().toString().trim(); + if (!newPath.isEmpty()) { + prefs.setFolderPath(newPath); + textCurrentPath.setText("Current: " + newPath); + } + finish(); + }); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_back.xml b/app/src/main/res/drawable/ic_back.xml new file mode 100644 index 0000000..0cdf891 --- /dev/null +++ b/app/src/main/res/drawable/ic_back.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_image_viewer.xml b/app/src/main/res/layout/activity_image_viewer.xml new file mode 100644 index 0000000..8ffd344 --- /dev/null +++ b/app/src/main/res/layout/activity_image_viewer.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9e910fa..ccb42b7 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,22 +1,28 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> - - - + + + - + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml new file mode 100644 index 0000000..24d2676 --- /dev/null +++ b/app/src/main/res/layout/activity_settings.xml @@ -0,0 +1,39 @@ + + + + + + + + + +