Java tutorial
/* * The MIT License (MIT) * * Copyright (c) 2014-2015 Umeng, Inc * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.umeng.comm.ui.fragments; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.TranslateAnimation; import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.umeng.comm.core.beans.CommConfig; import com.umeng.comm.core.beans.CommUser; import com.umeng.comm.core.beans.Comment; import com.umeng.comm.core.beans.FeedItem; import com.umeng.comm.core.beans.ForwardFeedItem; import com.umeng.comm.core.beans.Like; import com.umeng.comm.core.constants.Constants; import com.umeng.comm.core.db.AbsDBHelper; import com.umeng.comm.core.db.DbHelper; import com.umeng.comm.core.db.DbHelperFactory; import com.umeng.comm.core.db.cmd.DeleteCommand; import com.umeng.comm.core.db.cmd.InsertCommand; import com.umeng.comm.core.db.cmd.QueryCommand; import com.umeng.comm.core.db.cmd.concrete.DbCommandFactory; import com.umeng.comm.core.listeners.Listeners.CommListener; import com.umeng.comm.core.listeners.Listeners.FetchListener; import com.umeng.comm.core.listeners.Listeners.SimpleFetchListener; import com.umeng.comm.core.nets.Response; import com.umeng.comm.core.nets.responses.FeedsResponse; import com.umeng.comm.core.nets.responses.LoginResponse; import com.umeng.comm.core.nets.responses.SimpleResponse; import com.umeng.comm.core.utils.CommonUtils; import com.umeng.comm.core.utils.DeviceUtils; import com.umeng.comm.core.utils.Log; import com.umeng.comm.core.utils.ResFinder; import com.umeng.comm.core.utils.SharePrefUtils; import com.umeng.comm.core.utils.ToastMsg; import com.umeng.comm.ui.activities.FindActivity; import com.umeng.comm.ui.adapters.FeedAdapter; import com.umeng.comm.ui.adapters.FeedAdapter.InitListener; import com.umeng.comm.ui.adapters.viewparser.FeedItemViewParser.FeedItemViewHolder; import com.umeng.comm.ui.broadcastreceiver.NotifyBroadcastReceiver; import com.umeng.comm.ui.broadcastreceiver.NotifyBroadcastReceiver.NotifyListener; import com.umeng.comm.ui.broadcastreceiver.UserInfoNotifyListener; import com.umeng.comm.ui.dialogs.ConfirmDialog; import com.umeng.comm.ui.utils.Filter; import com.umeng.comm.ui.utils.ViewFinder; import com.umeng.comm.ui.widgets.CommentEditText; import com.umeng.comm.ui.widgets.CommentEditText.EditTextBackEventListener; import com.umeng.comm.ui.widgets.RefreshLayout.OnLoadListener; import com.umeng.comm.ui.widgets.RefreshLvLayout; import com.umeng.comm.ui.widgets.WrapperListView; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; /** * ???,FeedDetailFragment( * ??feed)???.???????????????????. * ?. * * @author mrsimple */ public abstract class BaseFeedsFragment extends FeedDetailFragment { /** * , , Feeds ListView */ protected RefreshLvLayout mRefreshLayout; /** * feeds ListView */ protected ListView mFeedsListView; /** * ??? */ protected FeedAdapter mFeedLvAdapter; /** * */ public CommentEditText mCommentEditText; /** * */ protected View mCommentLayout; /** * titleTextView */ protected TextView mTitleTextView; /** * ListViewfooters */ protected List<View> mFooterViews = new ArrayList<View>(); /** * ?OnGlobalLayoutListener???????listview */ private boolean isShowKeyboard = false; /** * ?filter */ protected Filter<FeedItem> mFeedFilter; /** * ???????? */ private OnGlobalLayoutListener mOnGlobalLayoutListener; /** * feed like?top and bottom padding */ private int mLikeItemPadding = 0; /** * */ protected CommUser mUser = CommConfig.getConfig().loginedUser; /** * ? */ NotifyBroadcastReceiver mUserBroadcastReceiver; /** * feed?? */ NotifyBroadcastReceiver mPostBroadcastReceiver; /** * ? */ protected NotifyBroadcastReceiver mBroadcastReceiver; /** * ???? */ protected AtomicBoolean isNeedRemoveOldFeeds = new AtomicBoolean(true); protected String mNextPageUrl = ""; private boolean hasRefresh = false; private int totalTime = 0; private boolean isFinish = false; private InputMethodManager mInputMan; private int mSlop; List<String> mTabTitls = new ArrayList<String>(); /** * ?feedbutton */ protected ImageView mPostBtn; /** * button */ protected ImageView mLocationBtn; /** * Handler???? */ @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { View view = (View) msg.obj; // if (msg.what == Constants.INPUT_METHOD_SHOW) { boolean result = mInputMan.showSoftInput(view, 0); if (!result && totalTime < Constants.LIMIT_TIME) { totalTime += Constants.IDLE; Message message = Message.obtain(msg); mHandler.sendMessageDelayed(message, Constants.IDLE); } else if (!isFinish) { totalTime = 0; result = view.requestFocus(); isFinish = true; } } else if (msg.what == Constants.INPUT_METHOD_DISAPPEAR) { // ?? mInputMan.hideSoftInputFromWindow(view.getWindowToken(), 0); } } }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); mRootView = inflater.inflate(ResFinder.getLayout("umeng_comm_feeds_frgm_layout"), container, false); mInputMan = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); // ? initViews(); // ?ActionButtonlike?????Dialog View initWidgets(); // ?Feed Adapter initAdapter(); // registerBroadcast(); // cache?? loadFeedsFromDB(); // ? mRefreshLayout.setRefreshing(true); // server?? fetchFeeds(); mSlop = ViewConfiguration.get(container.getContext()).getScaledTouchSlop(); return mRootView; } /** * ?feed? ?View */ protected void initViews() { mViewFinder = new ViewFinder(mRootView); // ?View initRefreshView(); // ?Title View // initTitleView(); // ? initCommentView(); mPostBtn = mViewFinder.findViewById(ResFinder.getId("umeng_comm_new_post_btn")); mLocationBtn = mViewFinder.findViewById(ResFinder.getId("umeng_comm_new_location_btn")); } /** * ?, listview */ private void initRefreshView() { // , mRefreshLayout = mViewFinder.findViewById(ResFinder.getId("umeng_comm_swipe_layout")); // mRefreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { // feed fetchFeeds(); } }); // mRefreshLayout.setOnLoadListener(new OnLoadListener() { @Override public void onLoad() { loadMoreFeed(); } }); // ?, ?? mRefreshLayout.addOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) { mImageLoader.resume(); } else { mImageLoader.pause(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); int feedListViewResId = ResFinder.getId("umeng_comm_feed_listview"); // feed listview mFeedsListView = mRefreshLayout.findRefreshViewById(feedListViewResId); // footer mRefreshLayout.setDefaultFooterView(); // mFeedsListView.setAnimationCacheEnabled(false); // ?smooth scrool bar mFeedsListView.setSmoothScrollbarEnabled(true); // EditTexttouchListviewLayout????? mFeedsListView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (mCommentLayout.isShown()) { hideCommentLayoutAndInputMethod(); return true; } return false; } }); mFeedsListView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { checkWhetherExecuteAnimation(event); if (mCommentLayout.isShown()) { hideCommentLayoutAndInputMethod(); return true; } return false; } }); } private int mLastScrollY = 0;// Y?? private static final int STATUS_NORMAL = 0x01;// ?? private static final int STATUS_SHOW = 0x02;// ? private static final int STATUS_DISMISS = 0x03;// ??? private transient int currentStatus = STATUS_NORMAL; // ?Float Button? private transient boolean isExecutingAnim = false; // ? /** * ?Float button</br> * * @param event */ private void checkWhetherExecuteAnimation(MotionEvent event) { int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mLastScrollY = y; break; case MotionEvent.ACTION_MOVE: int deltaY = mLastScrollY - y; mLastScrollY = y; if (Math.abs(deltaY) < mSlop) { return; } if (deltaY > 0) { executeAnimation(false); } else { executeAnimation(true); } break; default: break; } } /** * Float button</br> * * @param show or ? */ private void executeAnimation(final boolean show) { if (isExecutingAnim || (show && currentStatus == STATUS_SHOW) || (!show && currentStatus == STATUS_DISMISS)) { return; } isExecutingAnim = true; int moveDis = ((FrameLayout.LayoutParams) (mPostBtn.getLayoutParams())).bottomMargin + mPostBtn.getHeight(); Animation animation = null; if (show) { animation = new TranslateAnimation(0, 0, moveDis, 0); } else { animation = new TranslateAnimation(0, 0, 0, moveDis); } animation.setDuration(300); animation.setFillAfter(true); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { isExecutingAnim = false; if (show) { currentStatus = STATUS_SHOW; } else { currentStatus = STATUS_DISMISS; } // 3.0???????Float // Button?layout? mPostBtn.setClickable(show); } }); mPostBtn.startAnimation(animation); } /** * ??</br> */ public void hideCommentLayoutAndInputMethod() { resetCommentLayout(); hideInputMethod(); showPostButtonWithAnim(); } /** * </br> */ private void showInputMethod() { sendInputMethodMessage(Constants.INPUT_METHOD_SHOW, mCommentEditText); } /** * </br> */ private void hideInputMethod() { if (CommonUtils.isActivityAlive(getActivity())) { sendInputMethodMessage(Constants.INPUT_METHOD_DISAPPEAR, mCommentEditText); mRootView.getViewTreeObserver().removeGlobalOnLayoutListener(mOnGlobalLayoutListener); } } /** * */ protected void showPostButtonWithAnim() { } /** * */ private void hidePostButtonWithAnim() { AlphaAnimation animation = new AlphaAnimation(1.0f, 0f); animation.setDuration(500); mPostBtn.setVisibility(View.GONE); mPostBtn.startAnimation(animation); } @Override protected void initButtonsClickListener(FeedItemViewHolder viewHolder, final FeedItem feedItem, int position) { super.initButtonsClickListener(viewHolder, feedItem, position); viewHolder.mDialogButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mCurFeedItem = feedItem; showSelectDialog(); } }); } @Override protected FeedItem findFeedWithId(String feedId) { if (mCurFeedItem.id.equals(feedId)) { return mCurFeedItem; } List<FeedItem> allFeedItems = mFeedLvAdapter.getDataSource(); for (FeedItem feedItem : allFeedItems) { if (feedId.equals(feedItem.id)) { return feedItem; } } return new FeedItem(); } private String[] prepareMenus() { String[] menus = null; if (isMyFeed(mCurFeedItem)) { menus = new String[] { ResFinder.getString("umeng_comm_delete_feed_tips") }; } else { menus = new String[] { ResFinder.getString("umeng_comm_report_feed_tips") }; } return menus; } private void showSelectDialog() { AlertDialog.Builder dBuilder = new AlertDialog.Builder(getActivity()); final String[] menus = prepareMenus(); dBuilder.setItems(menus, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, final int which) { dialog.dismiss(); final String msg = menus[which] + ResFinder.getString("umeng_comm_this_feed"); showOprationDialog(msg, which); } }); dBuilder.create().show(); } private void showOprationDialog(String msg, final int which) { ConfirmDialog.showDialog(getActivity(), msg, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int invalid) { // feed if (which == 0 && isMyFeed(mCurFeedItem) && isDeletable(mCurFeedItem)) { deleteCurrentFeed(); } else if (which != -1) { reportCurrentFeed(); } } }); } /** * ?feed????Toast?? feed0???{@link FeedItem} * satus</br> * * @param item * @return */ private boolean isDeletable(FeedItem item) { if (item.status <= FeedItem.STATUS_VOTED) { return true; } ToastMsg.showShortMsgByResName(getActivity(), "umeng_comm_user_name_feed_invalid"); return false; } @Override protected void deleteInvalidateFeed(FeedItem feedItem) { super.deleteInvalidateFeed(feedItem); // feedlistview mFeedLvAdapter.getDataSource().remove(feedItem); mFeedLvAdapter.notifyDataSetChanged(); } /** * server?feed</br> */ private void deleteCurrentFeed() { mSdkImpl.deleteFeed(mCurFeedItem.id, new CommListener() { @Override public void onStart() { } @Override public void onComplete(Response data) { // ?? if (data.errCode == Constants.USER_FORBIDDEN_ERR_CODE) { ToastMsg.showShortMsg(getActivity(), ResFinder.getString("umeng_comm_user_unusable")); return; } if (data.errCode == 0) { updateAfterDelete(mCurFeedItem); deleteFeedFromDB(); } final String toast = data.errCode == 0 ? ResFinder.getString("umeng_comm_delete_success") : ResFinder.getString("umeng_comm_delete_failed"); ToastMsg.showShortMsg(getActivity(), toast); } }); } protected void updateAfterDelete(FeedItem feedItem) { mFeedLvAdapter.getDataSource().remove(feedItem); mFeedLvAdapter.notifyDataSetChanged(); // ?? sendDeleteFeedBrocast(feedItem); } private void sendDeleteFeedBrocast(FeedItem feedItem) { Intent intent = new Intent(NotifyBroadcastReceiver.FEED_DELETED); intent.putExtra(Constants.FEED, feedItem); getActivity().sendBroadcast(intent); } /** * ?feed</br> */ private void deleteFeedFromDB() { Map<String, String> wheres = new HashMap<String, String>(); wheres.put(AbsDBHelper.ID, mCurFeedItem.id); // DbHelper<FeedItem> helper = DbHelperFactory.getFeedDbHelper(getActivity()); DeleteCommand<FeedItem> deleteCommand = new DeleteCommand<FeedItem>(helper, wheres); helper.setOnItemFetchedListener(null); deleteCommand.execute(); } private void reportCurrentFeed() { SimpleFetchListener<LoginResponse> loginListener = new SimpleFetchListener<LoginResponse>() { @Override public void onComplete(LoginResponse response) { if (response.errCode == Constants.NO_ERROR) { // feed mSdkImpl.spammerFeed(mCurFeedItem.id, new FetchListener<SimpleResponse>() { @Override public void onStart() { } @Override public void onComplete(SimpleResponse response) { if (response.errCode == Constants.NO_ERROR) { ToastMsg.showShortMsgByResName(getActivity(), "umeng_comm_text_spammer_success"); } else if (response.errCode == Constants.SPAMMERED_CODE) { ToastMsg.showShortMsgByResName(getActivity(), "umeng_comm_text_spammered"); } else { ToastMsg.showShortMsgByResName(getActivity(), "umeng_comm_text_spammer_failed"); } } }); } } }; CommonUtils.checkLoginAndFireCallback(getActivity(), loginListener); } /** * */ private void initCommentView() { int commentLayoutResId = ResFinder.getId("umeng_comm_commnet_edit_layout"); // mCommentLayout = mRootView.findViewById(commentLayoutResId); int commentEditTextResId = ResFinder.getId("umeng_comm_comment_edittext"); mCommentEditText = mViewFinder.findViewById(commentEditTextResId); mCommentEditText.setEditTextBackListener(new EditTextBackEventListener() { @Override public void onClickBack() { // mCommentLayout.setVisibility(View.INVISIBLE); resetCommentLayout(); showPostButtonWithAnim(); } }); int sendButtonId = ResFinder.getId("umeng_comm_comment_send_button"); // ? mRootView.findViewById(sendButtonId).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final String commentText = mCommentEditText.getText().toString(); boolean result = checkCommentData(commentText); if (result) { postComment(commentText, mPostCommentListener); } else { ToastMsg.showShortMsgByResName(getActivity(), "umeng_comm_content_invalid"); } } }); } /** * feed?feed</br> * * @param feedItems feed * @return */ private List<FeedItem> getNewFeedItems(List<FeedItem> feedItems) { List<FeedItem> notExsitFeeds = removeExsitItems(mFeedLvAdapter.getDataSource(), feedItems); // ? return filteFeeds(notExsitFeeds); } /** * ?adapter?,?</br> * * @param feedItems */ protected void addFeedItemsToHeader(List<FeedItem> feedItems) { feedItems = removeSpamFeed(feedItems); List<FeedItem> olds = mFeedLvAdapter.getDataSource(); olds.removeAll(feedItems); olds.addAll(0, feedItems); // feedfeed????????feed?? Collections.sort(olds, mComparator); mFeedLvAdapter.notifyDataSetChanged(); } /** * ?adapter?,??</br> * * @param feedItems */ protected List<FeedItem> appendFeedItems(List<FeedItem> feedItems) { List<FeedItem> newFeeds = getNewFeedItems(feedItems); // listview mFeedLvAdapter.addData(newFeeds); return newFeeds; } /** * ??? */ private CommListener mPostCommentListener = new CommListener() { @Override public void onStart() { hideCommentLayoutAndInputMethod(); } @Override public void onComplete(Response resp) { if (resp.errCode == Constants.NO_ERROR) { resetCommentLayout(); // // feedlistviewlistviewviewstub inflate? // // ? // mCommentListView.setVisibility(View.VISIBLE); } } }; @Override protected void savePostedComment(Comment comment, String commId) { mCommentEditText.setText(""); super.savePostedComment(comment, commId); } /** * [ ???? ] * * @param oldItems ?listview? * @param newItems ?? * @return */ protected <T> List<T> removeExsitItems(List<T> oldItems, List<T> newItems) { // ?feeds oldItems.removeAll(newItems); return newItems; } protected void parseNextpageUrl(List<FeedItem> items, boolean fromRefersh) { if (items == null || items.size() == 0) { return; } if (fromRefersh && TextUtils.isEmpty(mNextPageUrl) && !hasRefresh) { hasRefresh = true; mNextPageUrl = items.get(0).nextPageUrl; } else if (!fromRefersh) { mNextPageUrl = items.get(items.size() - 1).nextPageUrl; } } /** * ?</br> */ protected void loadMoreFeed() { // ? if (!DeviceUtils.isNetworkAvailable(getActivity())) { loadFeedsFromDB(); return; } if (TextUtils.isEmpty(mNextPageUrl)) { ToastMsg.showShortMsgByResName(getActivity(), "umeng_comm_text_load_over"); mRefreshLayout.setLoading(false); return; } mSdkImpl.fetchNextPageData(mNextPageUrl, FeedsResponse.class, new SimpleFetchListener<FeedsResponse>() { @Override public void onComplete(FeedsResponse response) { mRefreshLayout.setLoading(false); Log.d(getTag(), "### ? : " + response.result.size()); // ?responseToast if (handlerResponse(response)) { return; } parseNextpageUrl(response.result, false); // ??feed final List<FeedItem> feedItems = filteFeeds(response.result); if (feedItems != null && feedItems.size() > 0) { removeSpamFeed(feedItems); // ? appendFeedItems(feedItems); saveFeedsToDB(feedItems); } } }); } /** * >=2feed</br> * * @param items * @return */ protected List<FeedItem> removeSpamFeed(List<FeedItem> items) { Iterator<FeedItem> iterator = items.iterator(); while (iterator.hasNext()) { FeedItem item = iterator.next(); if (item.status >= 2) { iterator.remove(); } } return items; } /** * cache?</br> */ protected void loadFeedsFromDB() { // ? if (CommonUtils.isActivityAlive(getActivity()) /* && !TextUtils.isEmpty(mUser.id) */) { executeLoadFeedsCommand(); } else { mRefreshLayout.setLoading(false); } } /** * ?feed */ protected void executeLoadFeedsCommand() { // ,?feed QueryCommand<FeedItem> feedQueryCommand = DbCommandFactory.createQueryFeedCmd(getActivity(), mUser.id, mFeedLvAdapter.getCount()); // ?ListView,???? feedQueryCommand.setOnItemFetchedListener(new SimpleFetchListener<FeedItem>() { @Override public void onComplete(FeedItem response) { if (CommonUtils.isActivityAlive(getActivity())) { dealFeedData(response); if (mImageLoader != null) { mImageLoader.resume(); } } } }); // ? feedQueryCommand.setFetchListener(new SimpleFetchListener<List<FeedItem>>() { @Override public void onComplete(List<FeedItem> response) { mRefreshLayout.setLoading(false); } }); feedQueryCommand.execute(); } /** * feed??</br> * * @param data */ protected void dealFeedData(FeedItem data) { List<FeedItem> items = new ArrayList<FeedItem>(); items.add(data); items = getNewFeedItems(items); if (items.size() > 0) { // ?Listview addNewFeed(items.get(0)); } } /** * feedlistview. [ ???? ] * * @param feedItem */ protected void addNewFeed(FeedItem feedItem) { final List<FeedItem> lists = mFeedLvAdapter.getDataSource(); lists.add(feedItem); Collections.sort(lists, mComparator); mFeedLvAdapter.updateListViewData(lists); } protected Comparator<FeedItem> mComparator = new Comparator<FeedItem>() { @Override public int compare(FeedItem lhs, FeedItem rhs) { return rhs.publishTime.compareTo(lhs.publishTime); } }; /** * ?? */ public void initAdapter() { if (mFeedLvAdapter == null) { mFeedLvAdapter = new FeedAdapter(getActivity(), new ArrayList<FeedItem>()); } mFeedLvAdapter.setInitItemListener(new InitListener() { @Override public void initItem(View rootView, final FeedItemViewHolder holder, final int position) { // likepaddingitem calculateLikePadding(holder.mLikeView); // get FeedItem at position final FeedItem feedItem = mFeedLvAdapter.getItem(position); // ? setFeedItemData(rootView, feedItem, position); // ? initButtonsClickListener(holder, feedItem, position); } }); mFeedsListView.setAdapter(mFeedLvAdapter); } private void calculateLikePadding(View likeView) { if (mLikeItemPadding == 0) { mLikeItemPadding = likeView.getPaddingBottom() + likeView.getPaddingTop(); } } // /** // * ??Title // */ // protected void initTitleView() { // int titleLayoutResId = ResFinder.getId("topic_action_bar"); // mTitleLayout = mRootView.findViewById(titleLayoutResId); // mTitleLayout.setVisibility(View.GONE); // // // // mProfileBtn = // mViewFinder.findViewById(ResFinder.getId("umeng_comm_user_info_btn")); // mProfileBtn.setOnClickListener(new OnClickListener() { // // @Override // public void onClick(View v) { // // gotoUserInfoActivity(CommConfig.getConfig().loginedUser); // gotoFindActivity(CommConfig.getConfig().loginedUser); // } // }); // // mPostBtn = // mViewFinder.findViewById(ResFinder.getId("umeng_comm_new_post_btn")); // // mTabTitls.add(""); // // mTabTitls.add("?"); // mTabTitls.add("??"); // // SlidingTextView textView = // mViewFinder.findViewById(ResFinder.getId("umeng_comm_title_tv")); // // TextView textView = // mViewFinder.findViewById(ResFinder.getId("umeng_comm_title_tv")); // textView.setSlidingAdapter(new SlidingAdapter() { // // @Override // public String getTitle(int position) { // return mTabTitls.get(position); // } // // @Override // public int getCount() { // return mTabTitls.size(); // } // }); // textView.setOnIndexChangeListener(new OnIndexChangeListener() { // // @Override // public void onChange(int oldIndex, int index) { // Log.d(getTag(), "### old index = " + oldIndex + ", new index " + index); // backData(oldIndex); // fetchNewFeedsWithIndex(index); // } // }); // } // /** // * @param index // */ // private void backData(int oldIndex) { // if (oldIndex == 0) { // mMainFeedList = mFeedLvAdapter.getDataSource(); // } else if (oldIndex == 1) { // mMomentsFeedList = mFeedLvAdapter.getDataSource(); // } else { // mRecommendFeedList = mFeedLvAdapter.getDataSource(); // } // } // private void fetchNewFeedsWithIndex(int newIndex) { // if (newIndex == 0) { // mFeedLvAdapter.addData(mMainFeedList); // fetchFeeds(); // } // // else if (newIndex == 1) { // // mFeedLvAdapter.addData(mMomentsFeedList); // // fetchMomentsFeeds(); // // } // else { // mFeedLvAdapter.addData(mRecommendFeedList); // fetchRecomendedFeeds(); // } // } // /** // * ??feed? // */ // private void fetchMomentsFeeds() { // // } /** * ?Activity</br> * * @param user */ public void gotoFindActivity(final CommUser user) { CommonUtils.checkLoginAndFireCallback(getActivity(), new SimpleFetchListener<LoginResponse>() { @Override public void onComplete(LoginResponse response) { Intent intent = new Intent(getActivity(), FindActivity.class); if (user == null) {// ?? intent.putExtra(Constants.TAG_USER, CommConfig.getConfig().loginedUser); } else { intent.putExtra(Constants.TAG_USER, user); } intent.putExtra(Constants.TYPE_CLASS, mContainerClass); getActivity().startActivity(intent); } }); } @Override public void onResume() { super.onResume(); mFeedsListView.postDelayed(new Runnable() { @Override public void run() { hideInputMethod(); if (mImageLoader != null) { // ?? mImageLoader.resume(); } } }, 300); // registerPostNotifyReceiver(); // registerUserInfoReceiver(); // removeDeletedFeeds(); } public void onStop() { resetCommentLayout(); super.onStop(); } NotifyListener mPostedNotifyListener = new NotifyListener() { @Override public void onNotify(Intent intent) { mFeedsListView.scrollTo(0, 0); mFeedsListView.invalidate(); fetchFeeds(); } }; protected boolean isMyPage(FeedItem feedItem) { return feedItem != null; } /** * ??feed</br> */ protected void registerBroadcast() { mBroadcastReceiver = new NotifyBroadcastReceiver(new NotifyListener() { @Override public void onNotify(Intent intent) { CommUser user = intent.getExtras().getParcelable(Constants.USER); List<FeedItem> items = mFeedLvAdapter.getDataSource(); List<FeedItem> scrapItems = new ArrayList<FeedItem>(); for (FeedItem item : items) { if (item.creator.equals(user)) { scrapItems.add(item); } } if (scrapItems.size() > 0) { mFeedLvAdapter.getDataSource().removeAll(scrapItems); mFeedLvAdapter.notifyDataSetChanged(); } } }); IntentFilter intentFilter = new IntentFilter(NotifyBroadcastReceiver.CANCEL_FOLLOWED); getActivity().registerReceiver(mBroadcastReceiver, intentFilter); } protected void registerPostNotifyReceiver() { if (mPostBroadcastReceiver == null) { mPostBroadcastReceiver = new NotifyBroadcastReceiver(new NotifyListener() { @Override public void onNotify(Intent intent) { FeedItem feedItem = intent.getExtras().getParcelable(Constants.FEED); if (!isMyPage(feedItem)) { return; } final String action = intent.getAction(); if (action.equals(NotifyBroadcastReceiver.FEED_POSTED)) { Log.d(getTag(), "### feed : " + feedItem); mFeedLvAdapter.addToFirst(feedItem); mFeedsListView.setSelection(0); // [???feed??feed] // fetchFeeds(); } else if (action.equals(NotifyBroadcastReceiver.FEED_DELETED)) { if (feedItem != null) { mFeedLvAdapter.getDataSource().remove(feedItem); mFeedLvAdapter.notifyDataSetChanged(); Log.d(getTag(), "### feed"); } } mFeedsListView.invalidate(); } }); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(NotifyBroadcastReceiver.FEED_POSTED); intentFilter.addAction(NotifyBroadcastReceiver.FEED_DELETED); // post getActivity().registerReceiver(mPostBroadcastReceiver, intentFilter); } } NotifyListener mUserInfoListener = new UserInfoNotifyListener() { @Override public void onNotify(Intent intent) { CommUser user = newUser(intent); if (user != null) { mUser = user; updatedUserInfo(mUser); } } }; /** * */ private void registerUserInfoReceiver() { if (mUserBroadcastReceiver == null) { mUserBroadcastReceiver = new NotifyBroadcastReceiver(mUserInfoListener); getActivity().registerReceiver(mUserBroadcastReceiver, new IntentFilter(NotifyBroadcastReceiver.USER_INFO_UPDATED)); } } /** * Feed???</br> * * @param feedItem * @return */ protected boolean isMyFeed(FeedItem feedItem) { CommUser user = CommConfig.getConfig().loginedUser; if (user == null || TextUtils.isEmpty(user.id)) { return false; } return feedItem.creator.id.equals(user.id); } /** * ??feed? * * @param user */ public void updatedUserInfo(CommUser user) { mUser = user; List<FeedItem> feedItems = mFeedLvAdapter.getDataSource(); for (FeedItem feed : feedItems) { updateFeedDetail(feed, user); } mFeedLvAdapter.notifyDataSetChanged(); } private void updateFeedDetail(FeedItem feed, CommUser user) { if (isMyFeed(feed)) { feed.creator = user; Log.d(getTag(), " : " + user.name); } // like? updateLikeCreator(feed.likes, user); // ? updateCommentCreator(feed.comments, user); // at?creator updateAtFriendCreator(feed.atFriends, user); // ?feed if (feed instanceof ForwardFeedItem) { updateFeedDetail(((ForwardFeedItem) feed).forwardItem, user); } } private void updateLikeCreator(List<Like> likes, CommUser user) { for (Like likeItem : likes) { if (likeItem.creator.id.equals(user.id)) { likeItem.creator = user; } } } private void updateCommentCreator(List<Comment> comments, CommUser user) { for (Comment commentItem : comments) { if (commentItem.creator.id.equals(user.id)) { commentItem.creator = user; } } } private void updateAtFriendCreator(List<CommUser> friends, CommUser user) { for (CommUser item : friends) { if (item.id.equals(user.id)) { item = user; } } } /** * feed?,Feed??ListView?.feedSharedPreferences?. */ private void removeDeletedFeeds() { SharedPreferences deletedSharedPref = SharePrefUtils.getSharePrefEdit(getActivity(), Constants.DELETED_FEEDS_PREF); // all deleted feeds iterator. Iterator<String> deletedIterator = deletedSharedPref.getAll().keySet().iterator(); // ???feed while (deletedIterator.hasNext()) { String feedId = deletedIterator.next(); // Iterator<FeedItem> feedIterator = mFeedLvAdapter.getDataSource().iterator(); // find the target feed while (feedIterator.hasNext()) { FeedItem feedItem = feedIterator.next(); if (feedItem.id.equals(feedId)) { feedIterator.remove(); break; } } // end of second while } // first while mFeedLvAdapter.notifyDataSetChanged(); deletedSharedPref.edit().clear(); } /** * feed</br> * * @param filter */ public void setFeedFilter(Filter<FeedItem> filter) { mFeedFilter = filter; } /** * ?FeedListView</br> * * @return */ public ListView getListView() { return mFeedsListView; } /** * ?</br> * * @return */ protected List<FeedItem> filteFeeds(List<FeedItem> list) { List<FeedItem> destList = mFeedFilter != null ? mFeedFilter.doFilte(list) : list; // status>=2feed?? Iterator<FeedItem> iterator = destList.iterator(); while (iterator.hasNext()) { FeedItem item = iterator.next(); if (item.status > 1) { iterator.remove(); } } return destList; } /** * Server?feed */ protected abstract void fetchFeeds(); /** * ???DB???Insert?. * * @param newFeedItems */ protected void saveFeedsToDB(final List<FeedItem> newFeedItems) { DbHelper<FeedItem> helper = DbHelperFactory.getFeedDbHelper(getActivity()); InsertCommand<FeedItem> insertCommand = new InsertCommand<FeedItem>(helper, newFeedItems); insertCommand.execute(); } /** * ??</br> * * @param content * @return */ private boolean checkCommentData(String content) { // ?? if (TextUtils.isEmpty(content)) { ToastMsg.showShortMsgByResName(getActivity(), "umeng_comm_content_invalid"); return false; } return true; } /** * ???? */ private void performListenKeyboard() { if (mOnGlobalLayoutListener == null) { mOnGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { final int screenHeight = mRootView.getRootView().getHeight(); int keyboardHeight = screenHeight - mRootView.getHeight(); // ??1/3? if (keyboardHeight < screenHeight / 3 || !isShowKeyboard) { return; } // ? isShowKeyboard = false; final int[] layoutSize = new int[2]; mCommentLayout.getLocationOnScreen(layoutSize); mFeedsListView.post(new Runnable() { @Override public void run() { int dis = 0; dis = layoutSize[1] + mScrollDis; if (mCommentListView != null) { dis -= mCommentListView.getPaddingBottom() + mCommentListView.getPaddingTop(); } if (mClickItemView != null) { dis -= mClickItemView.getHeight(); } mFeedsListView.setSelectionFromTop( mCurFeedItemIndex + mFeedsListView.getHeaderViewsCount(), dis); } }); } }; } // GlobalLayoutListener mRootView.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); } /* * */ @Override protected void showCommentLayout(final int pos, boolean fromClickBtn) { mRootView.post(new Runnable() { @Override public void run() { mCommentLayout.setVisibility(View.VISIBLE); if (mCommentEditText.requestFocus()) { // showInputMethod(); } isShowKeyboard = true; performListenKeyboard(); hidePostButtonWithAnim(); // getCommentPrefix(pos); } }); } /** * ?</br> * * @param pos */ private void setCommentContent(int pos, boolean clickBtn) { // ??? if (clickBtn) { mReplyUser = null; mCommentEditText.setHint(""); return; } String replyText = getCommentHint(pos, clickBtn); mCommentEditText.setHint(replyText); } /** * Comment itemitem????Editview? */ @Override protected void performClickCommentItem(final WrapperListView commListView, final View itemView, final int position, boolean clickBtn) { mClickItemView = itemView; if (commListView != null) { // ? int lastVisible = commListView.getLastVisiblePosition(); mScrollDis = 0; for (int i = position; i < lastVisible; i++) { mScrollDis += commListView.getChildAt(i).getHeight(); } } // ?? setCommentContent(position, clickBtn); // ? showInputMethod(); showCommentLayout(position, clickBtn); } @Override protected void clickActionButton(FeedItemViewHolder viewHolder, int position) { mCurFeedItemIndex = position + 1; super.clickActionButton(viewHolder, position); } @Override protected void updateCommentListView(WrapperListView commentListView, FeedItem feedItem, Comment comment) { super.updateCommentListView(commentListView, feedItem, comment); mFeedLvAdapter.notifyDataSetChanged(); } @Override protected void likeSuccess(String feedId, String likeId) { super.likeSuccess(feedId, likeId); mFeedsListView.requestLayout(); // ? mFeedLvAdapter.notifyDataSetChanged(); } private void resetCommentLayout() { if (mCommentLayout != null) { mCommentLayout.setVisibility(View.INVISIBLE); } if (mCommentEditText != null) { mCommentEditText.setText(""); } } private void unregisterReceiver() { if (mPostBroadcastReceiver != null) { getActivity().unregisterReceiver(mPostBroadcastReceiver); } if (mUserBroadcastReceiver != null) { getActivity().unregisterReceiver(mUserBroadcastReceiver); } if (mBroadcastReceiver != null) { getActivity().unregisterReceiver(mBroadcastReceiver); } } @Override public void onDestroy() { unregisterReceiver(); super.onDestroy(); } /** * ??show or hide?</br> * * @param type * @param view */ private void sendInputMethodMessage(int type, View view) { Message message = mHandler.obtainMessage(type); message.obj = view; mHandler.sendMessage(message); } void cleanAdapterData() { mFeedLvAdapter.getDataSource().clear(); mFeedLvAdapter.notifyDataSetChanged(); } }