private void fetchForumList() { Message msg = Message.obtain(); msg.what = ThreadListFragment.STAGE_GET_WEBPAGE; mHandler.sendMessage(msg); mUrl = HiUtils.ThreadListUrl + mForumId + "&page=" + mPage; if (HiSettingsHelper.getInstance().isSortByPostTime(mForumId)) { mUrl += "&orderby=dateline"; } StringRequest sReq = new HiStringRequest(mUrl, new ThreadListListener(), new ThreadListErrorListener()); VolleyHelper.getInstance().add(sReq); }
@Override public void onErrorResponse(VolleyError error) { Logger.e(error); Message msg = Message.obtain(); msg.what = ThreadListFragment.STAGE_ERROR; Bundle b = new Bundle(); String text = "无法访问HiPDA, " + VolleyHelper.getErrorReason(error); b.putString(ThreadListFragment.STAGE_ERROR_KEY, text); msg.setData(b); mHandler.sendMessage(msg); if (HiSettingsHelper.getInstance().isErrorReportMode()) ACRAUtils.acraReport(error, "url=" + mUrl); synchronized (mLocker) { mRsp = null; mLocker.notify(); } }
@Override protected Void doInBackground(PostBean... postBeans) { PostBean postBean = postBeans[0]; String replyText = postBean.getContent(); String tid = postBean.getTid(); String pid = postBean.getPid(); String fid = postBean.getFid(); String floor = postBean.getFloor(); String subject = postBean.getSubject(); String typeid = postBean.getTypeid(); int count = 0; while (mInfo == null && count < 3) { count++; mInfo = new PrePostAsyncTask(mCtx, null, mMode).doInBackground(postBean); } if (!TextUtils.isEmpty(floor) && TextUtils.isDigitsOnly(floor)) mFloor = floor; mContent = replyText; if (mMode != MODE_EDIT_POST) { String tail_text = HiSettingsHelper.getInstance().getTailText(); if (!tail_text.isEmpty() && HiSettingsHelper.getInstance().isAddTail()) { String tail_url = HiSettingsHelper.getInstance().getTailUrl(); if (!tail_url.isEmpty()) { if ((!tail_url.startsWith("http")) && (!tail_url.startsWith("https"))) { tail_url = "http://" + tail_url; } replyText = replyText + " [url=" + tail_url + "][size=1]" + tail_text + "[/size][/url]"; } else { replyText = replyText + " [size=1]" + tail_text + "[/size]"; } } } String url = HiUtils.ReplyUrl + tid + "&replysubmit=yes"; // do send switch (mMode) { case MODE_REPLY_THREAD: case MODE_QUICK_REPLY: doPost(url, replyText, null, null); break; case MODE_REPLY_POST: case MODE_QUOTE_POST: doPost(url, mInfo.getText() + "\n\n " + replyText, null, null); break; case MODE_NEW_THREAD: url = HiUtils.NewThreadUrl + fid + "&typeid=" + typeid + "&topicsubmit=yes"; doPost(url, replyText, subject, null); break; case MODE_EDIT_POST: url = HiUtils.EditUrl + "&extra=&editsubmit=yes&mod=&editsubmit=yes" + "&fid=" + fid + "&tid=" + tid + "&pid=" + pid + "&page=1"; doPost(url, replyText, subject, typeid); break; } return null; }
private void doPost(String url, String replyText, String subject, String typeid) { String formhash = mInfo != null ? mInfo.getFormhash() : null; if (TextUtils.isEmpty(formhash)) { mResult = "发表失败,无法获取必要信息 !"; mStatus = Constants.STATUS_FAIL; return; } Map<String, String> post_param = new HashMap<>(); post_param.put("formhash", formhash); post_param.put("posttime", String.valueOf(System.currentTimeMillis())); post_param.put("wysiwyg", "0"); post_param.put("checkbox", "0"); post_param.put("message", replyText); for (String attach : mInfo.getAttaches()) { post_param.put("attachnew[" + attach + "][description]", attach); } for (String attach : mInfo.getAttachdel()) { post_param.put("attachdel[" + attach + "]", attach); } for (String attach : mInfo.getUnusedImages()) { post_param.put("attachdel[" + attach + "]", attach); } if (mMode == MODE_NEW_THREAD) { post_param.put("subject", subject); post_param.put("attention_add", "1"); mTitle = subject; } else if (mMode == MODE_EDIT_POST) { if (!TextUtils.isEmpty(subject)) { post_param.put("subject", subject); mTitle = subject; if (!TextUtils.isEmpty(typeid)) { post_param.put("typeid", typeid); } } } SimpleErrorListener errorListener = VolleyHelper.getInstance().getErrorListener(); String rsp_str = VolleyHelper.getInstance().synchronousPost(url, post_param, errorListener); // when success, volley will follow 302 redirect get the page content if (!TextUtils.isEmpty(rsp_str)) { String tid = ""; if (rsp_str.contains("tid = parseInt('")) { tid = HttpUtils.getMiddleString(rsp_str, "tid = parseInt('", "'"); } if (!TextUtils.isEmpty(tid) && TextUtils.isDigitsOnly(tid) && Integer.parseInt(tid) > 0 && !rsp_str.contains("alert_info")) { mTid = tid; mResult = "发表成功!"; mStatus = Constants.STATUS_SUCCESS; } else { Logger.e(rsp_str); mResult = "发表失败! "; mStatus = Constants.STATUS_FAIL; Document doc = Jsoup.parse(rsp_str); Elements error = doc.select("div.alert_info"); if (error != null && error.size() > 0) { mResult += error.text(); } else { if (HiSettingsHelper.getInstance().isErrorReportMode()) ACRAUtils.acraReport("Error when posting but with response", rsp_str); } } } else { Logger.e(errorListener.getError()); mResult = "发表失败,无返回结果! " + errorListener.getErrorText(); mStatus = Constants.STATUS_FAIL; if (HiSettingsHelper.getInstance().isErrorReportMode()) ACRAUtils.acraReport(errorListener.getError(), "no response"); } }
public static boolean isDebug() { return BuildConfig.DEBUG || HiSettingsHelper.getInstance().isErrorReportMode(); }
private void showGotoPageDialog() { if (mAuthorOnly) { Toast.makeText(getActivity(), "请先退出只看楼主模式", Toast.LENGTH_LONG).show(); return; } mGoToPage = mCurrentPage; final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View viewlayout = inflater.inflate(R.layout.dialog_goto_page, null); final Button btnFirstPage = (Button) viewlayout.findViewById(R.id.btn_fisrt_page); final Button btnLastPage = (Button) viewlayout.findViewById(R.id.btn_last_page); final Button btnNextPage = (Button) viewlayout.findViewById(R.id.btn_next_page); final Button btnPreviousPage = (Button) viewlayout.findViewById(R.id.btn_previous_page); final SeekBar sbGotoPage = (SeekBar) viewlayout.findViewById(R.id.sb_page); final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); final AlertDialog dialog; // hack for IconicsButton conflict with custom font if (!TextUtils.isEmpty(HiSettingsHelper.getInstance().getFont())) { btnFirstPage.setText("首"); btnLastPage.setText("尾"); btnNextPage.setText("后"); btnPreviousPage.setText("前"); } builder.setTitle("第 " + String.valueOf(mGoToPage) + " / " + (mMaxPage) + " 页"); builder.setView(viewlayout); builder.setPositiveButton( getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { mCurrentPage = mGoToPage; showOrLoadPage(); } }); builder.setNegativeButton( getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog } }); dialog = builder.create(); // F**k Android SeekBar, always start from 0 sbGotoPage.setMax(mMaxPage - 1); sbGotoPage.setProgress(mCurrentPage - 1); sbGotoPage.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { mGoToPage = progress + 1; // start from 0 dialog.setTitle("第 " + String.valueOf(mGoToPage) + " / " + (mMaxPage) + " 页"); } @Override public void onStartTrackingTouch(SeekBar arg0) {} @Override public void onStopTrackingTouch(SeekBar arg0) {} }); btnFirstPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { mCurrentPage = 1; showOrLoadPage(); dialog.dismiss(); } }); btnLastPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { mCurrentPage = mMaxPage; mFloorOfPage = LAST_FLOOR; showOrLoadPage(); dialog.dismiss(); } }); btnNextPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { if (mCurrentPage < mMaxPage) { mCurrentPage++; showOrLoadPage(); } dialog.dismiss(); } }); btnPreviousPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { if (mCurrentPage > 1) { mCurrentPage--; showOrLoadPage(); } dialog.dismiss(); } }); dialog.show(); }
public class ThreadDetailFragment extends BaseFragment implements PostAsyncTask.PostListener { public static final String ARG_TID_KEY = "tid"; public static final String ARG_PID_KEY = "pid"; public static final String ARG_TITLE_KEY = "title"; public static final String ARG_FLOOR_KEY = "floor"; public static final String ARG_PAGE_KEY = "page"; public static final int LAST_FLOOR = Integer.MIN_VALUE; public static final int LAST_PAGE = Integer.MIN_VALUE; private Context mCtx; private String mTid; private String mGotoPostId; private String mTitle; private String mFid; private XListView mDetailListView; private TextView mTipBar; private TextView mTitleView; private ThreadListLoaderCallbacks mLoaderCallbacks; private ThreadDetailAdapter mDetailAdapter; private List<DetailBean> mDetailBeans = new ArrayList<>(); private int mMaxImageDecodeWidth = ImageSizeUtils.NORMAL_IMAGE_DECODE_WIDTH; public static int MAX_VIEW_WIDTH = 1080; private int mCurrentPage = 1; private int mMaxPage = 1; private int mGoToPage = 1; private int mMaxPostInPage = HiSettingsHelper.getInstance() .getMaxPostsInPage(); // user can configure max posts per page in forum setting private int mFloorOfPage = -1; // for every page start form 1 private boolean mInloading = false; private boolean mPrefetching = false; private TextView mReplyTextTv; private ImageButton mPostReplyIb; private View quickReply; private Handler mMsgHandler; private boolean mAuthorOnly = false; private ThreadDetailCache mCache = new ThreadDetailCache(); public static final String LOADER_PAGE_KEY = "LOADER_PAGE_KEY"; private HiProgressDialog postProgressDialog; private FloatingActionMenu mFam; @Override public void onCreate(Bundle savedInstanceState) { Logger.v("onCreate"); super.onCreate(savedInstanceState); ((MainFrameActivity) getActivity()).registOnSwipeCallback(this); mCtx = getActivity(); setHasOptionsMenu(true); if (getArguments().containsKey(ARG_TID_KEY)) { mTid = getArguments().getString(ARG_TID_KEY); } if (getArguments().containsKey(ARG_PID_KEY)) { mGotoPostId = getArguments().getString(ARG_PID_KEY); } if (getArguments().containsKey(ARG_TITLE_KEY)) { mTitle = getArguments().getString(ARG_TITLE_KEY); } if (getArguments().containsKey(ARG_PAGE_KEY)) { mCurrentPage = getArguments().getInt(ARG_PAGE_KEY); } if (getArguments().containsKey(ARG_FLOOR_KEY)) { mFloorOfPage = getArguments().getInt(ARG_FLOOR_KEY); } mLoaderCallbacks = new ThreadListLoaderCallbacks(); mDetailAdapter = new ThreadDetailAdapter( mCtx, getFragmentManager(), this, new GoToFloorOnClickListener(), new AvatarOnClickListener()); mMsgHandler = new Handler(new ThreadDetailMsgHandler()); } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Logger.v("onCreateView"); View view = inflater.inflate(R.layout.fragment_thread_detail, container, false); mDetailListView = (XListView) view.findViewById(R.id.lv_thread_details); mDetailListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); mTipBar = (TextView) view.findViewById(R.id.thread_detail_tipbar); mTipBar.bringToFront(); mFam = (FloatingActionMenu) view.findViewById(R.id.multiple_actions); mFam.setVisibility(View.INVISIBLE); FloatingActionButton fabRefresh = (FloatingActionButton) view.findViewById(R.id.action_fab_refresh); fabRefresh.setImageDrawable( new IconicsDrawable(getActivity(), GoogleMaterial.Icon.gmd_refresh).color(Color.WHITE)); fabRefresh.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { mFam.close(true); mFloorOfPage = LAST_FLOOR; refresh(); } }); FloatingActionButton fabQuickReply = (FloatingActionButton) view.findViewById(R.id.action_fab_quick_reply); fabQuickReply.setImageDrawable( new IconicsDrawable(getActivity(), GoogleMaterial.Icon.gmd_reply).color(Color.WHITE)); fabQuickReply.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { mFam.close(false); mFam.setVisibility(View.INVISIBLE); quickReply.setVisibility(View.VISIBLE); quickReply.bringToFront(); (new Handler()) .postDelayed( new Runnable() { public void run() { mReplyTextTv.requestFocus(); mReplyTextTv.dispatchTouchEvent( MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0)); mReplyTextTv.dispatchTouchEvent( MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0)); } }, 200); } }); FloatingActionButton fabGotoPage = (FloatingActionButton) view.findViewById(R.id.action_fab_goto_page); fabGotoPage.setImageDrawable( new IconicsDrawable(getActivity(), GoogleMaterial.Icon.gmd_swap_horiz).color(Color.WHITE)); fabGotoPage.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { mFam.close(true); showGotoPageDialog(); } }); if (!HiSettingsHelper.getInstance().getIsLandscape()) { mDetailListView.addHeaderView(inflater.inflate(R.layout.head_thread_detail, null)); mTitleView = (TextView) view.findViewById(R.id.thread_detail_title); mTitleView.setTextSize(HiSettingsHelper.getTitleTextSize()); mTitleView.setText(mTitle); } mDetailListView.setPullLoadEnable(false); mDetailListView.setPullRefreshEnable(false); mDetailListView.setXListViewListener( new XListView.IXListViewListener() { @Override public void onRefresh() { // Previous Page if (mCurrentPage > 1) { mCurrentPage--; } mDetailListView.stopRefresh(); mFloorOfPage = LAST_FLOOR; showOrLoadPage(); quickReply.setVisibility(View.INVISIBLE); } @Override public void onLoadMore() { // Next Page if (mCurrentPage < mMaxPage) { mCurrentPage++; } mDetailListView.stopLoadMore(); showOrLoadPage(); } }); final GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDoubleTap(MotionEvent e) { if (mDetailListView.isFastScrollEnabled()) { mDetailListView.setFastScrollEnabled(false); mDetailListView.setFastScrollAlwaysVisible(false); } else { mDetailListView.setFastScrollEnabled(true); mDetailListView.setFastScrollAlwaysVisible(true); } return true; } }; final GestureDetector detector = new GestureDetector(mCtx, listener); detector.setOnDoubleTapListener(listener); mDetailListView.setOnTouchListener( new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (mFam.isOpened()) { mFam.close(false); } return detector.onTouchEvent(event); } }); quickReply = view.findViewById(R.id.quick_reply); mReplyTextTv = (TextView) quickReply.findViewById(R.id.tv_reply_text); mReplyTextTv.setTextSize(HiSettingsHelper.getPostTextSize()); mPostReplyIb = (ImageButton) quickReply.findViewById(R.id.ib_reply_post); mPostReplyIb.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { String replyText = mReplyTextTv.getText().toString(); if (replyText.length() < 5) { Toast.makeText(getActivity(), "字数必须大于5", Toast.LENGTH_LONG).show(); } else { mReplyTextTv.setText(""); quickReply.setVisibility(View.INVISIBLE); PostBean postBean = new PostBean(); postBean.setContent(replyText); postBean.setTid(mTid); new PostAsyncTask( getActivity(), PostAsyncTask.MODE_QUICK_REPLY, null, ThreadDetailFragment.this) .execute(postBean); // Close SoftKeyboard InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mReplyTextTv.getWindowToken(), 0); mFam.setVisibility(View.VISIBLE); } } }); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { Logger.v("onActivityCreated"); super.onActivityCreated(savedInstanceState); mDetailListView.setAdapter(mDetailAdapter); mDetailListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); mDetailListView.setOnItemLongClickListener(new OnItemLongClickCallback()); mDetailListView.setOnScrollListener(new OnScrollCallback()); getLoaderManager().initLoader(0, new Bundle(), mLoaderCallbacks); showOrLoadPage(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { Logger.v("onCreateOptionsMenu"); menu.clear(); inflater.inflate(R.menu.menu_thread_detail, menu); setActionBarTitle(mTitle); setActionBarDisplayHomeAsUpEnabled(true); super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { Logger.v("onOptionsItemSelected"); switch (item.getItemId()) { case android.R.id.home: // Implemented in activity return false; case R.id.action_open_url: String url = HiUtils.DetailListUrl + mTid; Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); startActivity(i); return true; case R.id.action_copy_url: ClipboardManager clipboard = (ClipboardManager) mCtx.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("THREAD URL FROM HiPDA", HiUtils.DetailListUrl + mTid); clipboard.setPrimaryClip(clip); Toast.makeText(mCtx, "帖子地址已经复制到粘贴板", Toast.LENGTH_SHORT).show(); return true; case R.id.action_share_thread: Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); String shareBody = HiUtils.DetailListUrl + mTid + "\n" + "主题:" + mTitle + "\n"; if (mCache.get(1) != null && mCache.get(1).getAll().size() > 0) shareBody += ("作者:" + mCache.get(1).getAll().get(0).getAuthor()); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); startActivity(Intent.createChooser(sharingIntent, "分享帖子")); return true; case R.id.action_reply: setHasOptionsMenu(false); Bundle arguments = new Bundle(); arguments.putString(PostFragment.ARG_TID_KEY, mTid); arguments.putInt(PostFragment.ARG_MODE_KEY, PostAsyncTask.MODE_REPLY_THREAD); PostFragment fragment = new PostFragment(); fragment.setArguments(arguments); fragment.setPostListener(this); if (HiSettingsHelper.getInstance().getIsLandscape()) { getFragmentManager() .beginTransaction() .add(R.id.main_frame_container, fragment, PostFragment.class.getName()) .addToBackStack(PostFragment.class.getName()) .commit(); } else { getFragmentManager() .beginTransaction() .add(R.id.main_frame_container, fragment, PostFragment.class.getName()) .addToBackStack(PostFragment.class.getName()) .commit(); } return true; case R.id.action_refresh_detail: refresh(); return true; case R.id.action_image_gallery: startImageGallery(0); return true; // case R.id.action_goto: // showGotoPageDialog(); // return true; case R.id.action_only_author: mAuthorOnly = !mAuthorOnly; mDetailBeans.clear(); mDetailAdapter.setBeans(mDetailBeans); mCurrentPage = 1; if (mAuthorOnly) { mDetailListView.setPullLoadEnable(false); mDetailListView.setPullRefreshEnable(false); setActionBarTitle("(只看楼主)" + mTitle); showAndLoadAuthorOnly(); } else { showOrLoadPage(); } return true; case R.id.action_add_favorite: FavoriteHelper.getInstance().addFavorite(mCtx, mTid, mTitle); return true; case R.id.action_remove_favorite: FavoriteHelper.getInstance().removeFavorite(mCtx, mTid, mTitle); return true; default: return super.onOptionsItemSelected(item); } } private void refresh() { Bundle b = new Bundle(); b.putInt(LOADER_PAGE_KEY, mCurrentPage); getLoaderManager().restartLoader(0, b, mLoaderCallbacks).forceLoad(); } @Override public void onPrePost() { postProgressDialog = HiProgressDialog.show(mCtx, "正在发表..."); } @Override public void onPostDone(int mode, int status, String message, PostBean postBean) { if (status == Constants.STATUS_SUCCESS) { if (postProgressDialog != null) { postProgressDialog.dismiss(message); } else { Toast.makeText(mCtx, message, Toast.LENGTH_SHORT).show(); } if (!mAuthorOnly) { if (mode != PostAsyncTask.MODE_EDIT_POST) mCurrentPage = mMaxPage; int floor = LAST_FLOOR; if (!TextUtils.isEmpty(postBean.getFloor()) && TextUtils.isDigitsOnly(postBean.getFloor())) floor = Integer.parseInt(postBean.getFloor()); if (floor == LAST_FLOOR || floor > 0) mFloorOfPage = floor; mCache.remove(mCurrentPage); showOrLoadPage(); } } else { if (postProgressDialog != null) { postProgressDialog.dismissError(message); } else { Toast.makeText(mCtx, message, Toast.LENGTH_LONG).show(); } } } public DetailBean getCachedPost(String postId) { return mCache.getPostByPostId(postId); } private class OnScrollCallback implements AbsListView.OnScrollListener { private int mLastVisibleItem; private long lastUpdate = System.currentTimeMillis(); @Override public void onScroll( AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (!mInloading && !mPrefetching) { if (mLastVisibleItem < firstVisibleItem) { // scroll down, prefetch next page if (firstVisibleItem > Math.round(0.2f * totalItemCount)) { prefetchNextPage(1); } } if (mLastVisibleItem > firstVisibleItem) { // scroll up, prefetch previous page if (firstVisibleItem < Math.round(0.5f * totalItemCount)) { prefetchNextPage(-1); } } } long now = System.currentTimeMillis(); if (now - 200 > lastUpdate) { mLastVisibleItem = firstVisibleItem; lastUpdate = now; } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) {} } @Override public void onResume() { // Logger.v( "onResume"); super.onResume(); } @Override public void onPause() { // Logger.v( "onPause"); super.onPause(); } @Override public void onStop() { // Logger.v( "onStop"); super.onStop(); } @Override public void onDestroy() { // Logger.v( "onDestory"); getLoaderManager().destroyLoader(0); ((MainFrameActivity) getActivity()).registOnSwipeCallback(null); super.onDestroy(); } public class ThreadListLoaderCallbacks implements LoaderManager.LoaderCallbacks<DetailListBean> { @Override public Loader<DetailListBean> onCreateLoader(int id, Bundle args) { Logger.v("onCreateLoader"); if (mInloading) { return null; } // Re-enable after load complete if needed. mDetailListView.setPullLoadEnable(false); mDetailListView.setPullRefreshEnable(false); // VolleyHelper.getInstance().cancelAll(); return new DetailListLoader( mCtx, mMsgHandler, mTid, mGotoPostId, args.getInt(LOADER_PAGE_KEY, 1)); } @Override public void onLoadFinished(Loader<DetailListBean> loader, DetailListBean details) { Logger.v("onLoadFinished"); if (getView() != null) MAX_VIEW_WIDTH = getView().getWidth(); mInloading = false; mPrefetching = false; mMaxPostInPage = HiSettingsHelper.getInstance().getMaxPostsInPage(); mFam.setVisibility(View.VISIBLE); if (details == null) { // May be login error, error message should be populated in login async task return; } else if (details.getCount() == 0) { // Page load fail. Message msgError = Message.obtain(); msgError.what = ThreadListFragment.STAGE_ERROR; Bundle b = new Bundle(); b.putString(ThreadListFragment.STAGE_ERROR_KEY, "页面加载失败"); msgError.setData(b); mMsgHandler.sendMessage(msgError); return; } Message msgClean = Message.obtain(); msgClean.what = ThreadListFragment.STAGE_CLEAN; mMsgHandler.sendMessage(msgClean); // Set title if (details.getTitle() != null && !details.getTitle().isEmpty()) { mTitle = details.getTitle(); if (mTitleView != null) { mTitleView.setText(mTitle); } } mFid = details.getFid(); if (TextUtils.isEmpty(mTid)) mTid = details.getTid(); // Set MaxPage earlier than showOrLoadPage() mMaxPage = details.getLastPage(); // go to specific post id if (!TextUtils.isEmpty(mGotoPostId)) { mCurrentPage = details.getPage(); DetailBean detailBean = details.getPostInPage(mGotoPostId); // there is bug in search full text, given post id could'n found in thread int floor = 1; if (detailBean != null) floor = Integer.parseInt(detailBean.getFloor()); mFloorOfPage = floor % mMaxPostInPage; // floor start from 1 if (mFloorOfPage == 0) { mFloorOfPage = mMaxPostInPage; } mGotoPostId = null; } else if (mCurrentPage == LAST_PAGE) { mCurrentPage = mMaxPage; } mCache.put(details.getPage(), details); // set image's decode/display size base on image count mMaxImageDecodeWidth = ImageSizeUtils.getDecodeSize(details.getImagesCount()); if (!mAuthorOnly && mCurrentPage == details.getPage()) { showOrLoadPage(); } else if (mAuthorOnly) { showAndLoadAuthorOnly(); } setPullLoadStatus(); } @Override public void onLoaderReset(Loader<DetailListBean> arg0) { // Logger.v( "onLoaderReset"); mInloading = false; mPrefetching = false; } } private void prefetchNextPage(int pageOffset) { if (!mPrefetching && !mAuthorOnly && mCache.get(mCurrentPage + pageOffset) == null) { int page = mCurrentPage + pageOffset; if (page < 1 || page > mMaxPage) return; mPrefetching = true; Logger.v("prefetch page " + page); Bundle b = new Bundle(); b.putInt(LOADER_PAGE_KEY, page); getLoaderManager().restartLoader(0, b, mLoaderCallbacks).forceLoad(); } } private void setPullLoadStatus() { if (mAuthorOnly) { mDetailListView.setPullLoadEnable(false); mDetailListView.setPullRefreshEnable(false); } else { if (mCurrentPage == 1) { mDetailListView.setPullRefreshEnable(false); } else { mDetailListView.setPullRefreshEnable(true); } if (mCurrentPage == mMaxPage) { mDetailListView.setPullLoadEnable(false); } else { mDetailListView.setPullLoadEnable(true); } } } private class OnItemLongClickCallback implements AdapterView.OnItemLongClickListener { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { mDetailListView.setItemChecked(position, true); position = position - mDetailListView.getHeaderViewsCount(); if (position > mDetailAdapter.getCount()) { return false; } ThreadDetailActionModeCallback cb = new ThreadDetailActionModeCallback( ThreadDetailFragment.this, mFid, mTid, mDetailAdapter.getItem(position)); ((AppCompatActivity) getActivity()).startSupportActionMode(cb); return true; } } private void showGotoPageDialog() { if (mAuthorOnly) { Toast.makeText(getActivity(), "请先退出只看楼主模式", Toast.LENGTH_LONG).show(); return; } mGoToPage = mCurrentPage; final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View viewlayout = inflater.inflate(R.layout.dialog_goto_page, null); final Button btnFirstPage = (Button) viewlayout.findViewById(R.id.btn_fisrt_page); final Button btnLastPage = (Button) viewlayout.findViewById(R.id.btn_last_page); final Button btnNextPage = (Button) viewlayout.findViewById(R.id.btn_next_page); final Button btnPreviousPage = (Button) viewlayout.findViewById(R.id.btn_previous_page); final SeekBar sbGotoPage = (SeekBar) viewlayout.findViewById(R.id.sb_page); final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); final AlertDialog dialog; // hack for IconicsButton conflict with custom font if (!TextUtils.isEmpty(HiSettingsHelper.getInstance().getFont())) { btnFirstPage.setText("首"); btnLastPage.setText("尾"); btnNextPage.setText("后"); btnPreviousPage.setText("前"); } builder.setTitle("第 " + String.valueOf(mGoToPage) + " / " + (mMaxPage) + " 页"); builder.setView(viewlayout); builder.setPositiveButton( getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { mCurrentPage = mGoToPage; showOrLoadPage(); } }); builder.setNegativeButton( getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog } }); dialog = builder.create(); // F**k Android SeekBar, always start from 0 sbGotoPage.setMax(mMaxPage - 1); sbGotoPage.setProgress(mCurrentPage - 1); sbGotoPage.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { mGoToPage = progress + 1; // start from 0 dialog.setTitle("第 " + String.valueOf(mGoToPage) + " / " + (mMaxPage) + " 页"); } @Override public void onStartTrackingTouch(SeekBar arg0) {} @Override public void onStopTrackingTouch(SeekBar arg0) {} }); btnFirstPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { mCurrentPage = 1; showOrLoadPage(); dialog.dismiss(); } }); btnLastPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { mCurrentPage = mMaxPage; mFloorOfPage = LAST_FLOOR; showOrLoadPage(); dialog.dismiss(); } }); btnNextPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { if (mCurrentPage < mMaxPage) { mCurrentPage++; showOrLoadPage(); } dialog.dismiss(); } }); btnPreviousPage.setOnClickListener( new Button.OnClickListener() { @Override public void onClick(View view) { if (mCurrentPage > 1) { mCurrentPage--; showOrLoadPage(); } dialog.dismiss(); } }); dialog.show(); } public boolean hideQuickReply() { if (quickReply != null && quickReply.getVisibility() == View.VISIBLE) { mReplyTextTv.setText(""); quickReply.setVisibility(View.INVISIBLE); mFam.setVisibility(View.VISIBLE); return true; } return false; } public class GoToFloorOnClickListener implements Button.OnClickListener { @Override public void onClick(View view) { mAuthorOnly = false; int floor = (Integer) view.getTag(); mGoToPage = (floor - 1) / mMaxPostInPage + 1; // page start from 1 mFloorOfPage = floor % mMaxPostInPage; // floor start from 1 if (mFloorOfPage == 0) { mFloorOfPage = mMaxPostInPage; } if (mGoToPage != mCurrentPage) { mCurrentPage = mGoToPage; // getLoaderManager().restartLoader(0, null, mLoaderCallbacks).forceLoad(); showOrLoadPage(); } else { mDetailListView.setSelection(mFloorOfPage + mDetailListView.getHeaderViewsCount() - 1); mFloorOfPage = -1; } } } private class ThreadDetailMsgHandler implements Handler.Callback { @Override public boolean handleMessage(Message msg) { int page = 0; Bundle bundle = msg.getData(); if (bundle != null) { page = bundle.getInt(LOADER_PAGE_KEY, 0); } String pageStr = page > 0 ? "(第" + page + "页)" : ""; switch (msg.what) { case ThreadListFragment.STAGE_ERROR: mTipBar.setBackgroundColor(mCtx.getResources().getColor(R.color.red)); Bundle b = msg.getData(); mTipBar.setText(b.getString(ThreadListFragment.STAGE_ERROR_KEY)); Logger.e(b.getString(ThreadListFragment.STAGE_ERROR_KEY)); mTipBar.setVisibility(View.VISIBLE); break; case ThreadListFragment.STAGE_CLEAN: mTipBar.setVisibility(View.INVISIBLE); break; case ThreadListFragment.STAGE_DONE: mTipBar.setBackgroundColor(mCtx.getResources().getColor(R.color.green)); mTipBar.setText(pageStr + "加载完成"); mTipBar.setVisibility(View.VISIBLE); break; case ThreadListFragment.STAGE_RELOGIN: mTipBar.setBackgroundColor(mCtx.getResources().getColor(R.color.purple)); mTipBar.setText("正在登录"); mTipBar.setVisibility(View.VISIBLE); break; case ThreadListFragment.STAGE_GET_WEBPAGE: mTipBar.setBackgroundColor(mCtx.getResources().getColor(R.color.purple)); mTipBar.setText(pageStr + "正在获取页面"); mTipBar.setVisibility(View.VISIBLE); break; case ThreadListFragment.STAGE_PARSE: mTipBar.setBackgroundColor(mCtx.getResources().getColor(R.color.orange)); mTipBar.setText(pageStr + "正在解析页面"); mTipBar.setVisibility(View.VISIBLE); break; case ThreadListFragment.STAGE_PREFETCH: mTipBar.setBackgroundColor(mCtx.getResources().getColor(R.color.green)); mTipBar.setText("正在预读下一页"); mTipBar.setVisibility(View.VISIBLE); break; } return false; } } private void showOrLoadPage() { setActionBarTitle( "(" + (mCurrentPage > 0 ? String.valueOf(mCurrentPage) + "/" + String.valueOf(mMaxPage) + ")" : "") + mTitle); if (mCache.get(mCurrentPage) != null) { mDetailBeans.clear(); mDetailBeans.addAll(mCache.get(mCurrentPage).getAll()); mDetailAdapter.setBeans(mDetailBeans); if (mFloorOfPage == LAST_FLOOR) { mDetailListView.setSelection( mDetailAdapter.getCount() - 1 + mDetailListView.getHeaderViewsCount()); } else if (mFloorOfPage >= 0) { mDetailListView.setSelection(mFloorOfPage + mDetailListView.getHeaderViewsCount() - 1); } else { mDetailListView.setSelection(0); } mFloorOfPage = -1; mGotoPostId = null; // if current page loaded from cache, set prefetch flag for next page mPrefetching = false; setPullLoadStatus(); } else { Bundle b = new Bundle(); b.putInt(LOADER_PAGE_KEY, mCurrentPage); getLoaderManager().restartLoader(0, b, mLoaderCallbacks).forceLoad(); } } private void addAuthorPosts(DetailListBean details) { for (DetailBean detail : details.getAll()) { if (detail.getAuthor().equals(mCache.get(1).getAll().get(0).getAuthor())) { mDetailBeans.add(detail); } } mDetailAdapter.setBeans(mDetailBeans); } private void showAndLoadAuthorOnly() { while (mCache.get(mCurrentPage) != null && mCurrentPage <= mMaxPage) { addAuthorPosts(mCache.get(mCurrentPage)); mCurrentPage++; } if (mCurrentPage <= mMaxPage) { Bundle b = new Bundle(); b.putInt(LOADER_PAGE_KEY, mCurrentPage); getLoaderManager().restartLoader(0, b, mLoaderCallbacks).forceLoad(); } } public void loadImage(String imageUrl, GlideImageView giv) { if (mCtx == null) return; if (Build.VERSION.SDK_INT >= 17 && (mCtx instanceof Activity) && ((Activity) mCtx).isDestroyed()) return; if (!isAdded() || isDetached()) return; ImageReadyInfo imageReadyInfo = ImageContainer.getImageInfo(imageUrl); if (imageReadyInfo != null && imageReadyInfo.isReady()) { giv.getLayoutParams().width = imageReadyInfo.getWidth(); giv.getLayoutParams().height = imageReadyInfo.getHeight(); if (imageReadyInfo.getWidth() > GlideImageView.MIN_SCALE_WIDTH || imageReadyInfo.isGif()) { giv.setImageReadyInfo(imageReadyInfo); giv.setClickToViewBigImage(); } if (imageReadyInfo.isGif()) { Glide.with(mCtx) .load(GlideHelper.getGlideUrl(imageUrl)) .asBitmap() .diskCacheStrategy(DiskCacheStrategy.ALL) .transform(new GifTransformation(mCtx)) .into( new GlideBitmapTarget(giv, imageReadyInfo.getWidth(), imageReadyInfo.getHeight())); } else { Glide.with(mCtx) .load(GlideHelper.getGlideUrl(imageUrl)) .asBitmap() .cacheDecoder(new FileToStreamDecoder<>(new ThreadImageDecoder(mMaxImageDecodeWidth))) .imageDecoder(new ThreadImageDecoder(mMaxImageDecodeWidth)) .diskCacheStrategy(DiskCacheStrategy.ALL) .into( new GlideBitmapTarget(giv, imageReadyInfo.getWidth(), imageReadyInfo.getHeight())); } } else { giv.setImageResource(R.drawable.tapatalk_image_broken); } } class AvatarOnClickListener extends OnSingleClickListener { @Override public void onSingleClick(View arg0) { String uid = (String) arg0.getTag(R.id.avatar_tag_uid); String username = (String) arg0.getTag(R.id.avatar_tag_username); Bundle arguments = new Bundle(); arguments.putString(UserinfoFragment.ARG_UID, uid); arguments.putString(UserinfoFragment.ARG_USERNAME, username); UserinfoFragment fragment = new UserinfoFragment(); fragment.setArguments(arguments); setHasOptionsMenu(false); getFragmentManager() .beginTransaction() .setCustomAnimations( R.anim.slide_in_left, R.anim.slide_out_right, R.anim.slide_in_left, R.anim.slide_out_right) .add(R.id.main_frame_container, fragment, ThreadDetailFragment.class.getName()) .addToBackStack(ThreadDetailFragment.class.getName()) .commit(); } } public void startImageGallery(int imageIndex) { if (mAuthorOnly) { Toast.makeText(getActivity(), "请先退出只看楼主模式", Toast.LENGTH_LONG).show(); return; } DetailListBean detailListBean = mCache.get(mCurrentPage); if (detailListBean == null) { Toast.makeText(getActivity(), "帖子还未加载完成", Toast.LENGTH_LONG).show(); return; } if (detailListBean.getContentImages().size() > 0) { PopupImageDialog popupImageDialog = new PopupImageDialog(); popupImageDialog.init(detailListBean, imageIndex); popupImageDialog.show(getFragmentManager(), PopupImageDialog.class.getName()); } else { Toast.makeText(mCtx, "本页没有图片", Toast.LENGTH_SHORT).show(); } } }
@Override public void onLoadFinished(Loader<DetailListBean> loader, DetailListBean details) { Logger.v("onLoadFinished"); if (getView() != null) MAX_VIEW_WIDTH = getView().getWidth(); mInloading = false; mPrefetching = false; mMaxPostInPage = HiSettingsHelper.getInstance().getMaxPostsInPage(); mFam.setVisibility(View.VISIBLE); if (details == null) { // May be login error, error message should be populated in login async task return; } else if (details.getCount() == 0) { // Page load fail. Message msgError = Message.obtain(); msgError.what = ThreadListFragment.STAGE_ERROR; Bundle b = new Bundle(); b.putString(ThreadListFragment.STAGE_ERROR_KEY, "页面加载失败"); msgError.setData(b); mMsgHandler.sendMessage(msgError); return; } Message msgClean = Message.obtain(); msgClean.what = ThreadListFragment.STAGE_CLEAN; mMsgHandler.sendMessage(msgClean); // Set title if (details.getTitle() != null && !details.getTitle().isEmpty()) { mTitle = details.getTitle(); if (mTitleView != null) { mTitleView.setText(mTitle); } } mFid = details.getFid(); if (TextUtils.isEmpty(mTid)) mTid = details.getTid(); // Set MaxPage earlier than showOrLoadPage() mMaxPage = details.getLastPage(); // go to specific post id if (!TextUtils.isEmpty(mGotoPostId)) { mCurrentPage = details.getPage(); DetailBean detailBean = details.getPostInPage(mGotoPostId); // there is bug in search full text, given post id could'n found in thread int floor = 1; if (detailBean != null) floor = Integer.parseInt(detailBean.getFloor()); mFloorOfPage = floor % mMaxPostInPage; // floor start from 1 if (mFloorOfPage == 0) { mFloorOfPage = mMaxPostInPage; } mGotoPostId = null; } else if (mCurrentPage == LAST_PAGE) { mCurrentPage = mMaxPage; } mCache.put(details.getPage(), details); // set image's decode/display size base on image count mMaxImageDecodeWidth = ImageSizeUtils.getDecodeSize(details.getImagesCount()); if (!mAuthorOnly && mCurrentPage == details.getPage()) { showOrLoadPage(); } else if (mAuthorOnly) { showAndLoadAuthorOnly(); } setPullLoadStatus(); }
@Override public boolean onOptionsItemSelected(MenuItem item) { Logger.v("onOptionsItemSelected"); switch (item.getItemId()) { case android.R.id.home: // Implemented in activity return false; case R.id.action_open_url: String url = HiUtils.DetailListUrl + mTid; Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); startActivity(i); return true; case R.id.action_copy_url: ClipboardManager clipboard = (ClipboardManager) mCtx.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("THREAD URL FROM HiPDA", HiUtils.DetailListUrl + mTid); clipboard.setPrimaryClip(clip); Toast.makeText(mCtx, "帖子地址已经复制到粘贴板", Toast.LENGTH_SHORT).show(); return true; case R.id.action_share_thread: Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); String shareBody = HiUtils.DetailListUrl + mTid + "\n" + "主题:" + mTitle + "\n"; if (mCache.get(1) != null && mCache.get(1).getAll().size() > 0) shareBody += ("作者:" + mCache.get(1).getAll().get(0).getAuthor()); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); startActivity(Intent.createChooser(sharingIntent, "分享帖子")); return true; case R.id.action_reply: setHasOptionsMenu(false); Bundle arguments = new Bundle(); arguments.putString(PostFragment.ARG_TID_KEY, mTid); arguments.putInt(PostFragment.ARG_MODE_KEY, PostAsyncTask.MODE_REPLY_THREAD); PostFragment fragment = new PostFragment(); fragment.setArguments(arguments); fragment.setPostListener(this); if (HiSettingsHelper.getInstance().getIsLandscape()) { getFragmentManager() .beginTransaction() .add(R.id.main_frame_container, fragment, PostFragment.class.getName()) .addToBackStack(PostFragment.class.getName()) .commit(); } else { getFragmentManager() .beginTransaction() .add(R.id.main_frame_container, fragment, PostFragment.class.getName()) .addToBackStack(PostFragment.class.getName()) .commit(); } return true; case R.id.action_refresh_detail: refresh(); return true; case R.id.action_image_gallery: startImageGallery(0); return true; // case R.id.action_goto: // showGotoPageDialog(); // return true; case R.id.action_only_author: mAuthorOnly = !mAuthorOnly; mDetailBeans.clear(); mDetailAdapter.setBeans(mDetailBeans); mCurrentPage = 1; if (mAuthorOnly) { mDetailListView.setPullLoadEnable(false); mDetailListView.setPullRefreshEnable(false); setActionBarTitle("(只看楼主)" + mTitle); showAndLoadAuthorOnly(); } else { showOrLoadPage(); } return true; case R.id.action_add_favorite: FavoriteHelper.getInstance().addFavorite(mCtx, mTid, mTitle); return true; case R.id.action_remove_favorite: FavoriteHelper.getInstance().removeFavorite(mCtx, mTid, mTitle); return true; default: return super.onOptionsItemSelected(item); } }
@Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Logger.v("onCreateView"); View view = inflater.inflate(R.layout.fragment_thread_detail, container, false); mDetailListView = (XListView) view.findViewById(R.id.lv_thread_details); mDetailListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); mTipBar = (TextView) view.findViewById(R.id.thread_detail_tipbar); mTipBar.bringToFront(); mFam = (FloatingActionMenu) view.findViewById(R.id.multiple_actions); mFam.setVisibility(View.INVISIBLE); FloatingActionButton fabRefresh = (FloatingActionButton) view.findViewById(R.id.action_fab_refresh); fabRefresh.setImageDrawable( new IconicsDrawable(getActivity(), GoogleMaterial.Icon.gmd_refresh).color(Color.WHITE)); fabRefresh.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { mFam.close(true); mFloorOfPage = LAST_FLOOR; refresh(); } }); FloatingActionButton fabQuickReply = (FloatingActionButton) view.findViewById(R.id.action_fab_quick_reply); fabQuickReply.setImageDrawable( new IconicsDrawable(getActivity(), GoogleMaterial.Icon.gmd_reply).color(Color.WHITE)); fabQuickReply.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { mFam.close(false); mFam.setVisibility(View.INVISIBLE); quickReply.setVisibility(View.VISIBLE); quickReply.bringToFront(); (new Handler()) .postDelayed( new Runnable() { public void run() { mReplyTextTv.requestFocus(); mReplyTextTv.dispatchTouchEvent( MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0)); mReplyTextTv.dispatchTouchEvent( MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0)); } }, 200); } }); FloatingActionButton fabGotoPage = (FloatingActionButton) view.findViewById(R.id.action_fab_goto_page); fabGotoPage.setImageDrawable( new IconicsDrawable(getActivity(), GoogleMaterial.Icon.gmd_swap_horiz).color(Color.WHITE)); fabGotoPage.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { mFam.close(true); showGotoPageDialog(); } }); if (!HiSettingsHelper.getInstance().getIsLandscape()) { mDetailListView.addHeaderView(inflater.inflate(R.layout.head_thread_detail, null)); mTitleView = (TextView) view.findViewById(R.id.thread_detail_title); mTitleView.setTextSize(HiSettingsHelper.getTitleTextSize()); mTitleView.setText(mTitle); } mDetailListView.setPullLoadEnable(false); mDetailListView.setPullRefreshEnable(false); mDetailListView.setXListViewListener( new XListView.IXListViewListener() { @Override public void onRefresh() { // Previous Page if (mCurrentPage > 1) { mCurrentPage--; } mDetailListView.stopRefresh(); mFloorOfPage = LAST_FLOOR; showOrLoadPage(); quickReply.setVisibility(View.INVISIBLE); } @Override public void onLoadMore() { // Next Page if (mCurrentPage < mMaxPage) { mCurrentPage++; } mDetailListView.stopLoadMore(); showOrLoadPage(); } }); final GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDoubleTap(MotionEvent e) { if (mDetailListView.isFastScrollEnabled()) { mDetailListView.setFastScrollEnabled(false); mDetailListView.setFastScrollAlwaysVisible(false); } else { mDetailListView.setFastScrollEnabled(true); mDetailListView.setFastScrollAlwaysVisible(true); } return true; } }; final GestureDetector detector = new GestureDetector(mCtx, listener); detector.setOnDoubleTapListener(listener); mDetailListView.setOnTouchListener( new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (mFam.isOpened()) { mFam.close(false); } return detector.onTouchEvent(event); } }); quickReply = view.findViewById(R.id.quick_reply); mReplyTextTv = (TextView) quickReply.findViewById(R.id.tv_reply_text); mReplyTextTv.setTextSize(HiSettingsHelper.getPostTextSize()); mPostReplyIb = (ImageButton) quickReply.findViewById(R.id.ib_reply_post); mPostReplyIb.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { String replyText = mReplyTextTv.getText().toString(); if (replyText.length() < 5) { Toast.makeText(getActivity(), "字数必须大于5", Toast.LENGTH_LONG).show(); } else { mReplyTextTv.setText(""); quickReply.setVisibility(View.INVISIBLE); PostBean postBean = new PostBean(); postBean.setContent(replyText); postBean.setTid(mTid); new PostAsyncTask( getActivity(), PostAsyncTask.MODE_QUICK_REPLY, null, ThreadDetailFragment.this) .execute(postBean); // Close SoftKeyboard InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mReplyTextTv.getWindowToken(), 0); mFam.setVisibility(View.VISIBLE); } } }); return view; }