Android Open Source - wally Saved Images Fragment






From Project

Back to project page wally.

License

The source code is released under:

Apache License

If you think the Android project wally listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2014 Freddie (Musenkishi) Lust-Hed
 */*from   w  w  w . j  a v a 2  s  .c om*/
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.musenkishi.wally.fragments;

import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.FragmentManager;
import android.support.v7.view.ActionMode;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import com.musenkishi.wally.BuildConfig;
import com.musenkishi.wally.R;
import com.musenkishi.wally.activities.MainActivity;
import com.musenkishi.wally.adapters.RecyclerSavedImagesAdapter;
import com.musenkishi.wally.base.GridFragment;
import com.musenkishi.wally.observers.FileChangeReceiver;
import com.musenkishi.wally.util.SparseBooleanArrayParcelable;

import java.util.ArrayList;

import de.psdev.licensesdialog.LicensesDialogFragment;

/**
 * SavedImagesFragment is responsible to show the user all the wallpapers that has been saved.
 *
 * Created by Musenkishi on 2014-05-11.
 */
public class SavedImagesFragment extends GridFragment implements Handler.Callback, ActionMode.Callback {

    public static final String TAG = "com.musenkishi.wally.SavedImagesFragment";
    private static final String STATE_SELECTED_ITEMS = TAG + ".state.selectedItems";
    private static final int GET_IMAGES_FROM_STORAGE = 357;
    private static final int SET_IMAGES_TO_ADAPTER = 358;
    private static final int UPDATE_ADAPTER = 359;

    private ContentObserver contentObserver;

    private Handler uiHandler;

    private Cursor cursor;

    private RecyclerSavedImagesAdapter recyclerSavedImagesAdapter;
    private ActionMode actionMode;
    private SparseBooleanArrayParcelable selectedItems;

    public static SavedImagesFragment newInstance() {
        SavedImagesFragment fragment = new SavedImagesFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        setActionBarColor(getResources().getColor(R.color.Actionbar_Saved_Background));
        selectedItems = new SparseBooleanArrayParcelable();
        if (savedInstanceState != null) {
            selectedItems = savedInstanceState.getParcelable(STATE_SELECTED_ITEMS);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        if (rootView != null) {
            super.onCreateView(rootView);
            setupAutoSizeGridView();
            setupHandlers();
            showLoader();
        }
        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        gridView.setClipToPadding(false);
        setInsets(getActivity(), gridView, false, 0, 0);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            getImages(0, null);
        } else {
            if (actionMode != null) {
                actionMode.finish();
            }
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.images_saved, menu);

        MenuItem menuItemFilter = menu.findItem(R.id.action_licenses);

        if (menuItemFilter != null) {
            menuItemFilter.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    final LicensesDialogFragment fragment = LicensesDialogFragment.newInstance(R.raw.notices, false);
                    fragment.show(getFragmentManager(), null);
                    return false;
                }
            });
        }

        if (!BuildConfig.BUILD_TYPE.equalsIgnoreCase("release")){
            menu.add("Wally " + BuildConfig.VERSION_NAME);
        }

        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public void onResume() {
        super.onResume();
        getImages(0, null);
        initObserver(cursor);
    }

    @Override
    public void onPause() {
        if (cursor != null && contentObserver != null) {
            cursor.unregisterContentObserver(contentObserver);
        }
        super.onPause();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        if (recyclerSavedImagesAdapter != null) {
            outState.putParcelable(STATE_SELECTED_ITEMS, recyclerSavedImagesAdapter.getSelectedItems());
        }
        super.onSaveInstanceState(outState);
    }

    private void initObserver(Cursor cursor) {
        if (cursor != null) {
            if (contentObserver == null) {
                contentObserver = new ContentObserver(uiHandler) {
                    @Override
                    public void onChange(boolean selfChange) {
                        super.onChange(selfChange);
                        getImages(0, null);
                    }
                };

            }
            try {
                cursor.registerContentObserver(contentObserver);
            } catch (IllegalStateException e) {
                //Oh goodie, it's already registered. Nevermind then.
            }
        }
    }

    public String getRealPathFromURI(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] projection = {MediaStore.Images.Media.DATA};
            cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    private void setupHandlers() {
        uiHandler = new Handler(getActivity().getMainLooper(), this);
    }

    @Override
    protected void getImages(int index, String query) {
        if (!uiHandler.hasMessages(GET_IMAGES_FROM_STORAGE)) {
            uiHandler.sendEmptyMessage(GET_IMAGES_FROM_STORAGE);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        uiHandler.removeCallbacksAndMessages(null);
        cursor.close();
    }

    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case GET_IMAGES_FROM_STORAGE:
                if (getActivity() != null) {
                    String[] projection = {MediaStore.Images.Media._ID};
                    ContentResolver contentResolver = getActivity().getContentResolver();
                    Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

                    cursor = contentResolver.query(
                            mImageUri,
                            projection,
                            MediaStore.Images.Media.DATA + " like ? ",
                            new String[] {"%/Wally/%"},
                            MediaStore.Audio.Media.DATE_ADDED + " DESC");

                    initObserver(cursor);

                    int what;
                    if (recyclerSavedImagesAdapter == null) {
                        what = SET_IMAGES_TO_ADAPTER;
                    } else {
                        what = UPDATE_ADAPTER;
                    }
                    uiHandler.sendEmptyMessage(what);
                }
                break;

            case SET_IMAGES_TO_ADAPTER:
                hideLoader();
                recyclerSavedImagesAdapter = new RecyclerSavedImagesAdapter(getFileUrisFromCursor(cursor), itemSize, selectedItems);
                gridView.setAdapter(recyclerSavedImagesAdapter);
                setupAdapter(recyclerSavedImagesAdapter);
                gridView.scheduleLayoutAnimation();
                break;

            case UPDATE_ADAPTER:
                ArrayList<Uri> newFilePaths = getFileUrisFromCursor(cursor);
                ArrayList<Uri> oldFilePaths = recyclerSavedImagesAdapter.getData();
                recyclerSavedImagesAdapter.setData(newFilePaths);
                checkIfAddedOrRemovedItem(oldFilePaths, newFilePaths);
                break;

            default:
                break;
        }
        return false;
    }

    private ArrayList<Uri> getFileUrisFromCursor(Cursor cursor) {
        ArrayList<Uri> filePaths = new ArrayList<Uri>();
        if (cursor != null) {
            int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
            while (cursor.moveToNext()) {
                int imageID = cursor.getInt(columnIndex);
                Uri uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(imageID));
                filePaths.add(uri);
            }
        }
        return filePaths;
    }

    private void checkIfAddedOrRemovedItem(ArrayList<Uri> oldList, ArrayList<Uri> newList) {
        ArrayList<Uri> oldCompList = new ArrayList<Uri>(oldList);
        ArrayList<Uri> newCompList = new ArrayList<Uri>(newList);

        oldCompList.removeAll(newList);
        if (oldCompList.size() > 0) { //Items removed
            recyclerSavedImagesAdapter.notifyItemRangeRemoved(
                    oldList.indexOf(oldCompList.get(0)),
                    oldCompList.size()
            );
        }

        newCompList.removeAll(oldList);
        if (newCompList.size() > 0) { //Items added
            recyclerSavedImagesAdapter.notifyItemRangeInserted(
                    newList.indexOf(newCompList.get(0)),
                    newCompList.size()
            );
        }
    }

    public void setupAdapter(RecyclerSavedImagesAdapter adapter) {
        adapter.setOnItemClickListener(new RecyclerSavedImagesAdapter.OnItemClickListener() {
            @Override
            public void onClick(View view, int position) {
                if (recyclerSavedImagesAdapter.getSelectedItemCount() > 0) {
                    toggleSelection(position);
                } else {
                    Uri contentUri = recyclerSavedImagesAdapter.getItem(position);
                    Uri fileUri = Uri.parse("file://" + getRealPathFromURI(view.getContext(), contentUri));

                    FragmentManager fragmentManager = getFragmentManager();
                    if (fragmentManager != null) {
                        ImageZoomFragment imageZoomFragment = ImageZoomFragment.newInstance(fileUri, position);
                        imageZoomFragment.showFileOptions(fileUri, contentUri);
                        imageZoomFragment.show(fragmentManager, ImageZoomFragment.TAG);
                    }
                }
            }

            @Override
            public void onLongClick(View view, int position) {
                toggleSelection(position);
            }
        });
        toggleActionMode();
    }

    private void toggleSelection(int position) {
        recyclerSavedImagesAdapter.toggleSelection(position);
        toggleActionMode();
    }

    private void toggleActionMode() {
        if (recyclerSavedImagesAdapter.getSelectedItemCount() > 0) {
            if (actionMode == null) {
                actionMode = ((MainActivity) getActivity()).getSupportActionBar().startActionMode(this);
            }
            actionMode.setTitle(recyclerSavedImagesAdapter.getSelectedItemCount() + " checked");
        } else {
            if (actionMode != null) {
                actionMode.finish();
            }
        }
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.saved_images_context, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
        if (R.id.menu_delete == item.getItemId()) {

            int size = 0;

            SparseBooleanArray checkedItems = recyclerSavedImagesAdapter.getSelectedItems();
            for (int i = 0; i < checkedItems.size(); i++) {
                if (checkedItems.valueAt(i)) {
                    size++;
                }
            }

            String quantityString = getResources().getQuantityString(R.plurals.wallpapers, size);
            String title = String.format(getString(R.string.dialog_delete_title), quantityString);

            FragmentManager fragmentManager = getFragmentManager();

            if (fragmentManager != null) {
                final MaterialDialogFragment materialDialogFragment = new MaterialDialogFragment();
                materialDialogFragment.setPrimaryColor(getResources().getColor(R.color.Dialog_Button_Delete));
                materialDialogFragment.setTitle(title);
                materialDialogFragment.setPositiveButton(R.string.dialog_delete_positive, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        SparseBooleanArray checkedItems = recyclerSavedImagesAdapter.getSelectedItems();
                        for (int index = 0; index < checkedItems.size(); index++) {
                            if (checkedItems.valueAt(index)) {
                                Uri contentUri = recyclerSavedImagesAdapter.getItem(checkedItems.keyAt(index));
                                getActivity().getContentResolver().delete(contentUri, null, null);
                            }
                        }
                        mode.finish();
                        getImages(0, null);
                        getActivity().sendBroadcast(new Intent(FileChangeReceiver.FILES_CHANGED));
                    }
                });
                materialDialogFragment.setNegativeButton(R.string.dialog_delete_negative, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        materialDialogFragment.dismiss();
                    }
                });
                materialDialogFragment.show(fragmentManager, MaterialDialogFragment.TAG);
            }

        }
        return false;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        recyclerSavedImagesAdapter.clearSelections();
        actionMode = null;
    }
}




Java Source Code List

com.musenkishi.wally.activities.ImageDetailsActivity.java
com.musenkishi.wally.activities.MainActivity.java
com.musenkishi.wally.adapters.RecyclerImagesAdapter.java
com.musenkishi.wally.adapters.RecyclerSavedImagesAdapter.java
com.musenkishi.wally.adapters.SmartFragmentPagerAdapter.java
com.musenkishi.wally.adapters.SmartFragmentStatePagerAdapter.java
com.musenkishi.wally.anim.BaseItemAnimator.java
com.musenkishi.wally.anim.ScaleInOutItemAnimator.java
com.musenkishi.wally.anim.interpolator.EaseInOutBezierInterpolator.java
com.musenkishi.wally.anim.interpolator.FastOutLinearInInterpolator.java
com.musenkishi.wally.anim.interpolator.FastOutSlowInInterpolator.java
com.musenkishi.wally.anim.interpolator.LinearOutSlowInInterpolator.java
com.musenkishi.wally.base.BaseActivity.java
com.musenkishi.wally.base.BaseFragment.java
com.musenkishi.wally.base.GridFragment.java
com.musenkishi.wally.base.WallyApplication.java
com.musenkishi.wally.dataprovider.DataProvider.java
com.musenkishi.wally.dataprovider.FileManager.java
com.musenkishi.wally.dataprovider.NetworkDataProvider.java
com.musenkishi.wally.dataprovider.SharedPreferencesDataProvider.java
com.musenkishi.wally.dataprovider.models.DataProviderError.java
com.musenkishi.wally.dataprovider.models.SaveImageRequest.java
com.musenkishi.wally.dataprovider.okhttp.OkHttpStreamFetcher.java
com.musenkishi.wally.dataprovider.okhttp.OkHttpUrlLoader.java
com.musenkishi.wally.dataprovider.util.Parser.java
com.musenkishi.wally.fragments.CustomResolutionDialogFragment.java
com.musenkishi.wally.fragments.FilterDialogFragment.java
com.musenkishi.wally.fragments.ImageZoomFragment.java
com.musenkishi.wally.fragments.LatestFragment.java
com.musenkishi.wally.fragments.MaterialDialogFragment.java
com.musenkishi.wally.fragments.RandomImagesFragment.java
com.musenkishi.wally.fragments.SavedImagesFragment.java
com.musenkishi.wally.fragments.SearchFragment.java
com.musenkishi.wally.fragments.ToplistFragment.java
com.musenkishi.wally.models.Author.java
com.musenkishi.wally.models.ExceptionReporter.java
com.musenkishi.wally.models.Filter.java
com.musenkishi.wally.models.ImagePage.java
com.musenkishi.wally.models.Image.java
com.musenkishi.wally.models.ListFilterGroup.java
com.musenkishi.wally.models.Rating.java
com.musenkishi.wally.models.SavedImageData.java
com.musenkishi.wally.models.Size.java
com.musenkishi.wally.models.Tag.java
com.musenkishi.wally.models.filters.FilterAspectRatioKeys.java
com.musenkishi.wally.models.filters.FilterBoardsKeys.java
com.musenkishi.wally.models.filters.FilterBoards.java
com.musenkishi.wally.models.filters.FilterGroup.java
com.musenkishi.wally.models.filters.FilterGroupsStructure.java
com.musenkishi.wally.models.filters.FilterPurityKeys.java
com.musenkishi.wally.models.filters.FilterPurity.java
com.musenkishi.wally.models.filters.FilterResOptKeys.java
com.musenkishi.wally.models.filters.FilterResOpt.java
com.musenkishi.wally.models.filters.FilterResolutionKeys.java
com.musenkishi.wally.models.filters.FilterTimeSpanKeys.java
com.musenkishi.wally.muzei.WallyArtSource.java
com.musenkishi.wally.notification.NotificationProvider.java
com.musenkishi.wally.observers.FileChangeReceiver.java
com.musenkishi.wally.observers.FiltersChangeReceiver.java
com.musenkishi.wally.util.Blur.java
com.musenkishi.wally.util.PaletteLoader.java
com.musenkishi.wally.util.PaletteRequest.java
com.musenkishi.wally.util.SparseBooleanArrayParcelable.java
com.musenkishi.wally.util.TextClickableSpan.java
com.musenkishi.wally.util.TextLinkBuilder.java
com.musenkishi.wally.util.TypefaceSpan.java
com.musenkishi.wally.views.AutoGridView.java
com.musenkishi.wally.views.GridRecyclerView.java
com.musenkishi.wally.views.ObservableScrollView.java
com.musenkishi.wally.views.TabBarView.java
com.musenkishi.wally.views.TabView.java
com.musenkishi.wally.views.swipeclearlayout.SwipeClearLayout.java
net.margaritov.preference.colorpicker.dialog.ColorPickerDialogFragment.java
net.margaritov.preference.colorpicker.drawable.AlphaPatternDrawable.java
net.margaritov.preference.colorpicker.preference.ColorPickerPreference.java
net.margaritov.preference.colorpicker.view.ColorPanelView.java
net.margaritov.preference.colorpicker.view.ColorPickerView.java
nl.codesoup.cubicbezier.CubicBezierInterpolator.java