com.tweetlanes.android.core.view.UserFeedFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.tweetlanes.android.core.view.UserFeedFragment.java

Source

/*
 * Copyright (C) 2013 Chris Lacy 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.tweetlanes.android.core.view;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.ActionMode;
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 android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.ViewSwitcher;

import com.tweetlanes.android.core.App;
import com.tweetlanes.android.core.Constant;
import com.tweetlanes.android.core.Constant.SystemEvent;
import com.tweetlanes.android.core.R;
import com.tweetlanes.android.core.model.AccountDescriptor;
import com.tweetlanes.android.core.model.ComposeTweetDefault;
import com.tweetlanes.android.core.util.LazyImageLoader;
import com.tweetlanes.android.core.widget.pulltorefresh.PullToRefreshBase.OnLastItemVisibleListener;
import com.tweetlanes.android.core.widget.pulltorefresh.PullToRefreshBase.OnRefreshListener;
import com.tweetlanes.android.core.widget.pulltorefresh.PullToRefreshListView;

import org.tweetalib.android.TwitterConstant.UsersType;
import org.tweetalib.android.TwitterContentHandle;
import org.tweetalib.android.TwitterContentHandleBase;
import org.tweetalib.android.TwitterFetchResult;
import org.tweetalib.android.TwitterFetchUsers.FinishedCallback;
import org.tweetalib.android.TwitterManager;
import org.tweetalib.android.TwitterPaging;
import org.tweetalib.android.model.TwitterStatus;
import org.tweetalib.android.model.TwitterUser;
import org.tweetalib.android.model.TwitterUsers;

import java.util.ArrayList;

public class UserFeedFragment extends BaseLaneFragment {

    /*
     *
    */
    public static UserFeedFragment newInstance(int laneIndex, final TwitterContentHandleBase handleBase,
            final String screenName, final String laneIdentifier, final String currentAccountKey) {

        UserFeedFragment fragment = new UserFeedFragment();

        fragment.mContentHandle = TwitterManager.get().getContentHandle(handleBase, screenName, laneIdentifier,
                currentAccountKey);

        fragment.configureBaseLaneFragment(laneIndex, fragment.mContentHandle.getTypeAsString(),
                new ConfigureBundleListener() {

                    @Override
                    public void addValues(Bundle args) {
                        // TODO: serializing is a slow way of doing this...
                        args.putSerializable("handleBase", handleBase);
                        args.putString("screenName", screenName);
                        args.putString("laneIdentifier", laneIdentifier);
                    }

                });

        return fragment;
    }

    private PullToRefreshListView mUserFeedListView;
    private UserFeedListAdapter mUserFeedListAdapter;
    private TwitterContentHandle mContentHandle;
    private TwitterUsers _mUsersFeed;
    private FinishedCallback mUserDataRefreshCallback;
    private ViewSwitcher mViewSwitcher;
    private final ArrayList<TwitterUser> mSelectedItems = new ArrayList<TwitterUser>();

    private Long mNewestUserId;
    private Long mRefreshingNewestUserId;
    private Long mOldestUserId;
    private Long mRefreshingUserTweetId;
    private boolean mMoreUsersAvailable = true;

    /*
     *
    */
    public App getApp() {
        return (App) getActivity().getApplication();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
     * android.view.ViewGroup, android.os.Bundle)
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        super.onCreateView(inflater, container, savedInstanceState);

        mContentHandle = TwitterManager.get().getContentHandle(getContentHandleBase(), getScreenName(),
                getLaneIdentifier(), getApp().getCurrentAccountKey());

        if (mContentHandle == null) {
            // Occurs when coming back after the app was sleeping. Force refresh
            // of the adapter in this instance to ensure Fragments are created
            // correctly.
            showToast("No Content Handle found, forcing refresh");
            Intent intent = new Intent("" + SystemEvent.FORCE_FRAGMENT_PAGER_ADAPTER_REFRESH);
            LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
            return null;
        }

        //
        //
        //
        View resultView = inflater.inflate(R.layout.lane, null);
        configureLaneWidth(resultView);

        mViewSwitcher = (ViewSwitcher) resultView.findViewById(R.id.profileSwitcher);
        mUserFeedListAdapter = new UserFeedListAdapter(inflater);
        MultipleUserSelectionCallback multipleUserSelectionCallback = new MultipleUserSelectionCallback();
        mUserFeedListView = (PullToRefreshListView) resultView.findViewById(R.id.pull_to_refresh_listview);
        mUserFeedListView.getRefreshableView().setOnItemClickListener(mOnUserFeedItemClickListener);
        mUserFeedListView.getRefreshableView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        mUserFeedListView.getRefreshableView().setMultiChoiceModeListener(multipleUserSelectionCallback);
        mUserFeedListView.getRefreshableView().setOnScrollListener(mUserFeedOnScrollListener);
        mUserFeedListView.getRefreshableView().setAdapter(mUserFeedListAdapter);
        mUserFeedListView.setOnRefreshListener(mUserFeedOnRefreshListener);
        mUserFeedListView.setOnLastItemVisibleListener(mUserFeedOnLastItemVisibleListener);

        //
        //
        //
        TwitterUsers cachedUsers;
        if (mContentHandle.getUsersType() == UsersType.RETWEETED_BY) {
            cachedUsers = TwitterManager.get().getUsers(mContentHandle, TwitterPaging.createGetMostRecent(20));
        } else {
            cachedUsers = TwitterManager.get().getUsers(mContentHandle, null);
        }
        if (cachedUsers != null) {
            setUserFeed(cachedUsers);
        } else {
            setUserFeed(null);
        }

        if (getUserFeed() == null || getUserFeed().getUserCount() == 0) {
            updateViewVisibility(false);
            setInitialDownloadState(InitialDownloadState.WAITING);
        } else {
            setInitialDownloadState(InitialDownloadState.DOWNLOADED);
            updateViewVisibility(true);
        }

        return resultView;
    }

    private TwitterContentHandleBase getContentHandleBase() {
        return (TwitterContentHandleBase) getArguments().getSerializable("handleBase");
    }

    private String getScreenName() {
        return getArguments().getString("screenName");
    }

    private String getLaneIdentifier() {
        return getArguments().getString("laneIdentifier");
    }

    /*
     *
    */
    private void setUserFeed(TwitterUsers users) {

        mNewestUserId = null;
        mOldestUserId = null;

        if (users == null) {
            _mUsersFeed = null;
        } else {
            _mUsersFeed = new TwitterUsers(users);
            if (users.getUserCount() > 0) {
                mNewestUserId = users.getUser(0).getId();
                mOldestUserId = users.getUser(users.getUserCount() - 1).getId();
            }
        }
    }

    /*
    *
    */
    private TwitterUsers getUserFeed() {
        return _mUsersFeed;
    }

    /*
    *
    */
    private void onRefreshComplete(TwitterUsers feed) {

        if (feed != null) {
            setUserFeed(feed);
        }
        mUserFeedListAdapter.notifyDataSetChanged();
        mUserDataRefreshCallback = null;
    }

    /*
    *
    */
    private void updateViewVisibility(boolean loadHasFinished) {

        mViewSwitcher.reset();

        if (!loadHasFinished && (getUserFeed() == null || getUserFeed().getUserCount() == 0)) {
            mViewSwitcher.setDisplayedChild(0);
        } else {
            mViewSwitcher.setDisplayedChild(1);
            mUserFeedListAdapter.notifyDataSetChanged();
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see com.tweetlanes.android.core.view.BaseLaneFragment#UpdateTweetCache()
     */
    @Override
    public void UpdateTweetCache(TwitterStatus status, boolean deleteStatus) {

    }

    /*
     * (non-Javadoc)
     *
     * @see com.tweetlanes.android.core.view.BaseLaneFragment#onJumpToTop()
     */
    @Override
    public void onJumpToTop() {
        if (mUserFeedListView != null) {
            ListView listView = mUserFeedListView.getRefreshableView();
            if (listView != null && listView.getAdapter() != null && !listView.getAdapter().isEmpty()) {
                listView.setSelection(0);
            }
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see com.tweetlanes.android.core.view.BaseLaneFragment#clearLocalCache()
     */
    @Override
    public void clearLocalCache() {
        _mUsersFeed = null;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.tweetlanes.android.core.view.BaseLaneFragment#getContentToCache()
     */
    @Override
    public String getDataToCache() {
        return null;
    }

    /*
    *
    */
    private final OnScrollListener mUserFeedOnScrollListener = new OnScrollListener() {

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            mUserFeedListView.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
        }

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {

            if (scrollState == 0) {
                // Restore scrollbar fading, which may have been set to false
                // when scrolling through items via the volume keys
                view.setScrollbarFadingEnabled(true);
            }

            mUserFeedListView.onScrollStateChanged(view, scrollState);
        }

    };

    /*
    *
    */
    private final OnLastItemVisibleListener mUserFeedOnLastItemVisibleListener = new OnLastItemVisibleListener() {

        @Override
        public void onLastItemVisible() {

            mUserDataRefreshCallback = TwitterManager.get().getFetchUsersInstance().new FinishedCallback() {

                @Override
                public void finished(TwitterFetchResult result, TwitterUsers feed) {

                    onRefreshComplete(feed);

                    if (mRefreshingUserTweetId.longValue() == mOldestUserId.longValue()) {
                        mMoreUsersAvailable = false;
                    }
                    mRefreshingUserTweetId = null;
                }
            };

            if (mOldestUserId != null) {
                if (mRefreshingUserTweetId == null) {
                    // TODO: Bit of a hack, but does remove an unnecessary fetch
                    // that is triggered here when initializing
                    int count = mUserFeedListAdapter.getCount();
                    if (count > 2) {
                        mRefreshingUserTweetId = mOldestUserId;
                        TwitterManager.get().getUsers(mContentHandle, TwitterPaging.createGetOlder(mOldestUserId),
                                mUserDataRefreshCallback);
                    }
                }
            }
        }
    };

    /*
    *
    */
    private final OnRefreshListener mUserFeedOnRefreshListener = new OnRefreshListener() {

        @Override
        public void onRefresh() {

            mUserDataRefreshCallback = TwitterManager.get().getFetchUsersInstance().new FinishedCallback() {

                @Override
                public void finished(TwitterFetchResult result, TwitterUsers feed) {

                    onRefreshComplete(feed);
                    mUserFeedListView.onRefreshComplete();
                    mRefreshingNewestUserId = null;
                }
            };

            if (mNewestUserId != null) {
                if (mRefreshingNewestUserId == null) {
                    mRefreshingNewestUserId = mNewestUserId;
                    TwitterUsers users = TwitterManager.get().getUsers(mContentHandle,
                            TwitterPaging.createGetNewer(mNewestUserId), mUserDataRefreshCallback);
                    if (users == null) {
                        getBaseLaneActivity().finishCurrentActionMode();
                    }
                }
            } else {
                TwitterManager.get().getUsers(mContentHandle, null, mUserDataRefreshCallback);
                getBaseLaneActivity().finishCurrentActionMode();
            }
        }
    };

    /*
    *
    */
    private final OnItemClickListener mOnUserFeedItemClickListener = new OnItemClickListener() {

        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            // Ignore the PTR item
            position -= 1;

            if (position < getUserFeed().getUserCount()) {
                TwitterUser user = getUserFeed().getUser(position);
                Intent profileIntent = new Intent(getActivity(), ProfileActivity.class);
                profileIntent.putExtra("userId", Long.valueOf(user.getId()).toString());
                profileIntent.putExtra("userScreenName", user.getScreenName());
                getActivity().startActivityForResult(profileIntent, Constant.REQUEST_CODE_PROFILE);
            }
        }
    };

    /*
     *
     */
    private class MultipleUserSelectionCallback implements ListView.MultiChoiceModeListener {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {

            mode.getMenu().clear();
            MenuInflater inflater = getActivity().getMenuInflater();
            inflater.inflate(R.menu.users_selected, mode.getMenu());

            mode.setTitle("Select Users");

            configure(mode);
            return true;
        }

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

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

            final int itemId = item.getItemId();
            if (itemId == R.id.action_retweet || itemId == R.id.action_favorite
                    || itemId == R.id.action_manage_friendship) {
                showToast(getString(R.string.functionality_not_implemented));
                mode.finish();

            } else if (itemId == R.id.action_report_for_spam || itemId == R.id.action_block) {
                AccountDescriptor account = getApp().getCurrentAccount();
                if (account != null) {

                    TwitterUsers selected = getSelectedUsers();
                    if (selected != null && selected.getUserCount() > 0) {

                        ArrayList<Long> userIds = new ArrayList<Long>();
                        for (int i = 0; i < selected.getUserCount(); i++) {
                            userIds.add(selected.getUser(0).getId());
                        }

                        FinishedCallback callback = TwitterManager.get()
                                .getFetchUsersInstance().new FinishedCallback() {

                                    @Override
                                    public void finished(TwitterFetchResult result, TwitterUsers users) {
                                        getBaseLaneActivity().finishCurrentActionMode();

                                        if (getUserFeed() != null) {
                                            getUserFeed().remove(users);
                                        }

                                        onRefreshComplete(getUserFeed());
                                        mUserFeedListView.onRefreshComplete();
                                        updateViewVisibility(true);

                                        if (result.isSuccessful() && users != null && users.getUserCount() > 0) {
                                            int userCount = users.getUserCount();
                                            String notice;
                                            if (itemId == R.id.action_report_for_spam) {
                                                if (userCount == 1) {
                                                    notice = "Reported @" + users.getUser(0).getScreenName()
                                                            + " for Spam.";
                                                } else {
                                                    notice = "Reported " + userCount + " users for Spam.";
                                                }
                                            } else {
                                                if (userCount == 1) {
                                                    notice = "Blocked @" + users.getUser(0).getScreenName() + ".";
                                                } else {
                                                    notice = "Blocked " + userCount + " users.";
                                                }
                                            }
                                            if (notice != null) {
                                                showToast(notice);
                                            }
                                        }
                                    }
                                };

                        if (item.getItemId() == R.id.action_report_for_spam) {
                            TwitterManager.get().reportSpam(account.getId(), userIds, callback);
                        } else {
                            TwitterManager.get().createBlock(account.getId(), userIds, callback);
                        }
                    }
                }

            } else {
            }
            return true;
        }

        public void onDestroyActionMode(ActionMode mode) {
            mSelectedItems.clear();
            if (!getBaseLaneActivity().composeHasFocus()) {
                getBaseLaneActivity().setComposeDefault();
            }
        }

        public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
            onUserFeedItemViewClick(position, checked);
            configure(mode);
        }

        void configure(ActionMode mode) {

            BaseLaneActivity baseLaneActivity = (BaseLaneActivity) getActivity();
            if (baseLaneActivity == null || baseLaneActivity.isComposing() || mUserFeedListView == null
                    || mUserFeedListView.getRefreshableView() == null || mode == null) {
                return;
            }

            final int checkedCount = mUserFeedListView.getRefreshableView().getCheckedItemCount();
            switch (checkedCount) {
            case 0:
                mode.setSubtitle(null);
                break;

            default:
                mode.setSubtitle("" + checkedCount + " selected");
                break;
            }
        }

    }

    /*
    *
    */
    private void onUserFeedItemViewClick(int position, boolean checked) {

        position -= 1; // remove the pull-to-refresh item

        TwitterUser user = getUserFeed().getUser(position);

        for (int index = 0; index < mSelectedItems.size(); index++) {
            TwitterUser selectedUser = mSelectedItems.get(index);
            if (selectedUser != null && user != null) {
                if (selectedUser.getId() == user.getId()) {
                    mSelectedItems.remove(index);
                    break;
                }
            }
        }

        if (checked) {
            mSelectedItems.add(user);
        }

        if (mSelectedItems.size() > 0) {
            getBaseLaneActivity().setComposeTweetDefault(
                    new ComposeTweetDefault(getApp().getCurrentAccountScreenName(), getSelectedUsers()));
        } else {
            getBaseLaneActivity().setComposeDefault();
        }
    }

    /*
    *
    */
    private TwitterUsers getSelectedUsers() {

        TwitterUsers selectedList = new TwitterUsers();

        for (int i = 0; i < mSelectedItems.size(); i++) {
            TwitterUser selectedUser = mSelectedItems.get(i);
            if (selectedUser != null) {
                selectedList.add(selectedUser);
            }
        }

        return selectedList.getUserCount() > 0 ? selectedList : null;
    }

    /*
    *
    */
    /*
     * private TwitterUser getFirstSelectedUser() { for (int i = 0; i <
     * mSelectedItems.size(); i++) { UserFeedItemView userFeedItemView =
     * mSelectedItems.get(i); TwitterUser user =
     * userFeedItemView.getTwitterUser(); if (user != null) { return user; } }
     * return null; }
     */

    /*
     *
     */
    public interface UserFeedItemViewCallbacks {

        public Activity getActivity();

        public LazyImageLoader getProfileImageLoader();
    }

    /*
     *
     */
    private class UserFeedListAdapter extends BaseAdapter {

        public UserFeedListAdapter(LayoutInflater inflater) {
            mInflater = inflater;
        }

        /**
         * The number of items in the list is determined by the number of
         * speeches in our array.
         *
         * @see android.widget.ListAdapter#getCount()
         */
        public int getCount() {
            int count;
            if (getUserFeed() != null) {
                count = getUserFeed().getUserCount() + 1; // +1 for the trailing
                // LoadMore view
            } else {
                count = 1;
            }

            return count;
        }

        /**
         * Since the data comes from an array, just returning the index is
         * sufficent to get at the data. If we were using a more complex data
         * structure, we would return whatever object represents one row in the
         * list.
         *
         * @see android.widget.ListAdapter#getItem(int)
         */
        public Object getItem(int position) {
            return position;
        }

        /**
         * Use the array index as a unique id.
         *
         * @see android.widget.ListAdapter#getItemId(int)
         */
        public long getItemId(int position) {
            return position;
        }

        /**
         * Make a TweetFeedItemView to hold each row.
         */
        public View getView(int position, View convertView, ViewGroup parent) {

            int userCount = getUserFeed() != null ? getUserFeed().getUserCount() : 0;

            View resultView;
            if (userCount == 0 && position == getCount() - 1) {
                resultView = getLoadMoreView();
            } else if (position == userCount) {
                resultView = getLoadMoreView();
            } else {
                resultView = getUserFeedItemView(position);
            }

            return resultView;

        }

        /*
         *
         */
        View getUserFeedItemView(int position) {

            View convertView = mInflater.inflate(R.layout.user_feed_item, null);

            TwitterUser user = getUserFeed().getUser(position);

            UserFeedItemView userFeedItemView = (UserFeedItemView) convertView.findViewById(R.id.userFeedItem);

            UserFeedItemViewCallbacks callbacks = new UserFeedItemViewCallbacks() {

                @Override
                public Activity getActivity() {
                    return UserFeedFragment.this.getActivity();
                }

                @Override
                public LazyImageLoader getProfileImageLoader() {
                    return getApp().getProfileImageLoader();
                }

            };

            userFeedItemView.configure(user, position + 1, callbacks);
            return userFeedItemView;

        }

        /*
         *
         */
        View getLoadMoreView() {

            View convertView = mInflater.inflate(R.layout.load_more, null);
            LoadMoreView loadMoreView = (LoadMoreView) convertView.findViewById(R.id.loadMoreView);

            LoadMoreView.Mode mode;
            if (getUserFeed() == null || getUserFeed().getUserCount() == 0) {
                mode = LoadMoreView.Mode.NONE_FOUND;
            } else {
                mode = mMoreUsersAvailable ? LoadMoreView.Mode.LOADING : LoadMoreView.Mode.NO_MORE;
            }

            loadMoreView.configure(mode);
            return loadMoreView;
        }

        /**
         * Remember our context so we can use it when constructing views.
         */
        // private Context mContext;
        private final LayoutInflater mInflater;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * com.tweetlanes.android.core.view.BaseLaneFragment#triggerInitialDownload()
     */
    @Override
    public void triggerInitialDownload() {

        mUserDataRefreshCallback = TwitterManager.get().getFetchUsersInstance().new FinishedCallback() {

            @Override
            public void finished(TwitterFetchResult fetchResult, TwitterUsers users) {
                onRefreshComplete(users);
                if (mUserFeedListView != null) {
                    mUserFeedListView.onRefreshComplete();
                }

                updateViewVisibility(true);
                mUserDataRefreshCallback = null;

                setInitialDownloadState(InitialDownloadState.DOWNLOADED);
            }

        };

        TwitterUsers cachedUsers;
        if (mContentHandle.getUsersType() == UsersType.RETWEETED_BY) {
            cachedUsers = TwitterManager.get().getUsers(mContentHandle, TwitterPaging.createGetMostRecent(20),
                    mUserDataRefreshCallback);
        } else {
            cachedUsers = TwitterManager.get().getUsers(mContentHandle, null, mUserDataRefreshCallback);
        }

        if (cachedUsers != null) {
            if (mUserDataRefreshCallback != null) {
                mUserDataRefreshCallback.finished(new TwitterFetchResult(true, null), cachedUsers);
            }
        } else {
            setInitialDownloadState(InitialDownloadState.DOWNLOADING);
        }
    }

}