中文字幕第五页-中文字幕第页-中文字幕韩国-中文字幕最新-国产尤物二区三区在线观看-国产尤物福利视频一区二区

如何在Android應用中實現一個動態界面分享功能

如何在Android應用中實現一個動態界面分享功能?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

網站建設哪家好,找創新互聯建站!專注于網頁設計、網站建設、微信開發、重慶小程序開發、集團企業網站建設等服務項目。為回饋新老客戶創新互聯還提供了烏蘭免費建站歡迎大家使用!

動態列表界面MomentListFragment支持 下拉刷新與上拉加載 和 模糊搜索,反復快速滑動仍然非常流暢。

緩存機制使得數據可在啟動界面后瞬間加載完成。

如何在Android應用中實現一個動態界面分享功能

動態詳情界面MomentActivity支持 (取消)點贊、(刪除)評論、點擊姓名跳到個人詳情 等。

只有1張圖片時圖片放大顯示,超過1張則按九宮格顯示。

如何在Android應用中實現一個動態界面分享功能

用到的CommentContainerView和MomentView都是獨立的組件,既可單獨使用,也可用于ListView或添加至其它ViewGroup等。

CommentContainerView復用

如何在Android應用中實現一個動態界面分享功能如何在Android應用中實現一個動態界面分享功能

CommentContainerView.java

setOnCommentClickListener    : 設置點擊評論監聽
createView           : 創建View
bindView            : 綁定數據并顯示View
setMaxShowCount         : 設置最多顯示數量,超過則折疊
setComment           : 設置評論
addCommentView         : 添加評論View

 package apijson.demo.client.view;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import apijson.demo.client.R;
import apijson.demo.client.model.CommentItem;
import apijson.demo.client.view.CommentView.OnCommentClickListener;
import zuo.biao.library.base.BaseView;
import zuo.biao.library.util.Log;
import zuo.biao.library.util.StringUtil;
/**評論容器
 * @author Lemon
 * @use
CommentContainerView commentContainerView = new CommentContainerView(context, inflater);
adapter中使用convertView = commentContainerView.getView();//[具體見.DemoAdapter] 或 其它類中使用
containerView.addView(commentContainerView.getConvertView());
commentContainerView.bindView(data);
commentContainerView.setOnClickPictureListener(onClickPictureListener);//非必需
commentContainerView.setOnDataChangedListener(onDataChangedListener);data = commentContainerView.getData();//非必需
commentContainerView.setOnClickListener(onClickListener);//非必需
...
 */
public class CommentContainerView extends BaseView<List<CommentItem>> {
  private static final String TAG = "CommentContainerView";
  private OnCommentClickListener onCommentClickListener;
  /**設置點擊評論監聽
   * @param onCommentClickListener
   */
  public void setOnCommentClickListener(OnCommentClickListener onCommentClickListener) {
    this.onCommentClickListener = onCommentClickListener;
  }
  public CommentContainerView(Activity context, Resources resources) {
    super(context, resources);
  }
  private LayoutInflater inflater;
  public ViewGroup llCommentContainerViewContainer;
  public View tvCommentContainerViewMore;
  @SuppressLint("InflateParams")
  @Override
  public View createView(LayoutInflater inflater) {
    this.inflater = inflater;
    convertView = inflater.inflate(R.layout.comment_container_view, null);
    llCommentContainerViewContainer = findViewById(R.id.llCommentContainerViewContainer);
    tvCommentContainerViewMore = findViewById(R.id.tvCommentContainerViewMore);
    return convertView;
  }
  @Override
  public void bindView(List<CommentItem> list){
    llCommentContainerViewContainer.setVisibility(list == null || list.isEmpty() &#63; View.GONE : View.VISIBLE);
    if (list == null) {
      Log.w(TAG, "bindView data_ == null >> data_ = new List<CommentItem>();");
      list = new ArrayList<CommentItem>();
    }
    this.data = list;
    // 評論
    setComment(list);
  }
  private int maxShowCount = 3;
  /**設置最多顯示數量,超過則折疊
   * @param maxShowCount <= 0 &#63; 顯示全部 : 超過則折疊
   */
  public void setMaxShowCount(int maxShowCount) {
    this.maxShowCount = maxShowCount;
  }
  /**設置評論
   * @param list
   */
  public void setComment(List<CommentItem> list) {
    int count = list == null &#63; 0 : list.size();
    boolean showMore = maxShowCount > 0 && count > maxShowCount;
    tvCommentContainerViewMore.setVisibility(showMore &#63; View.VISIBLE : View.GONE);
    llCommentContainerViewContainer.removeAllViews();
    llCommentContainerViewContainer.setVisibility(count <= 0 &#63; View.GONE : View.VISIBLE);
    if (count > 0) {
      if (showMore) {
        list = list.subList(0, maxShowCount);
      }
      for (int i = 0; i < list.size(); i++) {
        addCommentView(i, list.get(i));
      }
    }
  }
  /**添加評論
   * @param index
   * @param comment
   */
  @SuppressLint("InflateParams")
  private void addCommentView(final int index, final CommentItem comment) {
    if (comment == null) {
      Log.e(TAG, "addCommentView comment == null >> return; ");
      return;
    }
    String content = StringUtil.getTrimedString(comment.getComment().getContent());
    if (StringUtil.isNotEmpty(content, true) == false) {
      Log.e(TAG, "addCommentView StringUtil.isNotEmpty(content, true) == false >> return; ");
      return;
    }
    CommentTextView commentView = (CommentTextView) inflater.inflate(R.layout.comment_item, null);
    commentView.setView(comment);
    if (onCommentClickListener != null) {
      commentView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
          onCommentClickListener.onCommentClick(comment, position, index, false);
        }
      });
      commentView.setOnLongClickListener(new OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
          onCommentClickListener.onCommentClick(comment, position, index, true);
          return true;
        }
      });
    }
    llCommentContainerViewContainer.addView(commentView);
  }
}

comment_container_view.xml

<&#63;xml version="1.0" encoding="utf-8"&#63;>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   >
  <LinearLayout
    android:id="@+id/llCommentContainerViewContainer"
     >
  </LinearLayout>
  <TextView
    android:id="@+id/tvCommentContainerViewMore"
    
    android:layout_width="match_parent"
    android:background="@drawable/bg_item_to_alpha"
    android:gravity="left|center_vertical"
    android:paddingBottom="4dp"
    android:paddingTop="4dp"
    android:text="查看全部" />
</LinearLayout>

MomentView復用

如何在Android應用中實現一個動態界面分享功能如何在Android應用中實現一個動態界面分享功能

MomentView.java

setOnPictureClickListener    : 設置點擊圖片監聽
createView           : 創建View
bindView            : 綁定數據并顯示View
setPraise            : 設置點贊
setShowComment         : 設置是否顯示評論
getShowComment         : 獲取是否顯示評論的設置
setComment           : 設置評論
setPicture           : 設置九宮格圖片
toComment            : 跳轉到所有評論界面
getData             : 獲取動態綁定的數據
isLoggedIn           : 判斷是否已登錄,未登錄則跳到登錄界面
praise             : (取消)點贊
onDialogButtonClick       : 處理對話框返回結果,比如刪除動態
onHttpResponse         : 處理Http請求的返回結果,比如點贊
onClick             : 處理點擊事件,比如點擊內容跳到動態詳情界面
onItemClick           : 處理點擊圖片的事件,默認是查看大圖,可setOnPictureClickListener接管處理

package apijson.demo.client.view;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import apijson.demo.client.R;
import apijson.demo.client.activity_fragment.LoginActivity;
import apijson.demo.client.activity_fragment.MomentActivity;
import apijson.demo.client.activity_fragment.UserActivity;
import apijson.demo.client.activity_fragment.UserListActivity;
import apijson.demo.client.application.APIJSONApplication;
import apijson.demo.client.model.CommentItem;
import apijson.demo.client.model.Moment;
import apijson.demo.client.model.MomentItem;
import apijson.demo.client.model.User;
import apijson.demo.client.util.HttpRequest;
import apijson.demo.client.view.CommentView.OnCommentClickListener;
import zuo.biao.apijson.JSONResponse;
import zuo.biao.library.base.BaseView;
import zuo.biao.library.manager.CacheManager;
import zuo.biao.library.manager.HttpManager.OnHttpResponseListener;
import zuo.biao.library.model.Entry;
import zuo.biao.library.ui.AlertDialog;
import zuo.biao.library.ui.AlertDialog.OnDialogButtonClickListener;
import zuo.biao.library.ui.GridAdapter;
import zuo.biao.library.ui.WebViewActivity;
import zuo.biao.library.util.ImageLoaderUtil;
import zuo.biao.library.util.Log;
import zuo.biao.library.util.ScreenUtil;
import zuo.biao.library.util.StringUtil;
import zuo.biao.library.util.TimeUtil;
/**動態
 * @author Lemon
 * @use
MomentView momentView = new MomentView(context, inflater);
adapter中使用convertView = momentView.getView();//[具體見.DemoAdapter] 或 其它類中使用
containerView.addView(momentView.getConvertView());
momentView.bindView(data);
momentView.setOnPictureClickListener(onPictureClickListener);//非必需
momentView.setOnDataChangedListener(onDataChangedListener);data = momentView.getData();//非必需
momentView.setOnClickListener(onClickListener);//非必需
...
 */
public class MomentView extends BaseView<MomentItem> implements OnClickListener
, OnHttpResponseListener, OnDialogButtonClickListener, OnItemClickListener {
  private static final String TAG = "MomentView";
  public interface OnPictureClickListener {
    void onClickPicture(int momentPosition, MomentView momentView, int pictureIndex);
  }
  private OnPictureClickListener onPictureClickListener;
  /**設置點擊圖片監聽
   * @param onPictureClickListener
   */
  public void setOnPictureClickListener(OnPictureClickListener onPictureClickListener) {
    this.onPictureClickListener = onPictureClickListener;
  }
  public MomentView(Activity context, Resources resources) {
    super(context, resources);
  }
  //UI顯示區(操作UI,但不存在數據獲取或處理代碼,也不存在事件監聽代碼)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  private LayoutInflater inflater;
  public View llMomentViewContainer;
  public ImageView ivMomentViewHead;
  public TextView tvMomentViewName;
  public TextView tvMomentViewStatus;
  public TextView tvMomentViewContent;
  public GridView gvMomentView;
  public TextView tvMomentViewDate;
  public ImageView ivMomentViewPraise;
  public ImageView ivMomentViewComment;
  public ViewGroup llMomentViewPraise;
  public PraiseTextView tvMomentViewPraise;
  public View vMomentViewDivider;
  public ViewGroup llMomentViewCommentContainer;
  @SuppressLint("InflateParams")
  @Override
  public View createView(LayoutInflater inflater) {
    this.inflater = inflater;
    convertView = inflater.inflate(R.layout.moment_view, null);
    llMomentViewContainer = findViewById(R.id.llMomentViewContainer);
    ivMomentViewHead = findViewById(R.id.ivMomentViewHead, this);
    tvMomentViewName = findViewById(R.id.tvMomentViewName, this);
    tvMomentViewStatus = findViewById(R.id.tvMomentViewStatus, this);
    tvMomentViewContent = findViewById(R.id.tvMomentViewContent, this);
    gvMomentView = findViewById(R.id.gvMomentView);
    tvMomentViewDate = findViewById(R.id.tvMomentViewDate);
    ivMomentViewPraise = findViewById(R.id.ivMomentViewPraise, this);
    ivMomentViewComment = findViewById(R.id.ivMomentViewComment, this);
    llMomentViewPraise = findViewById(R.id.llMomentViewPraise, this);
    tvMomentViewPraise = findViewById(R.id.tvMomentViewPraise, this);
    vMomentViewDivider = findViewById(R.id.vMomentViewDivider);
    llMomentViewCommentContainer = findViewById(R.id.llMomentViewCommentContainer);
    return convertView;
  }
  private User user;
  private Moment moment;
  private long momentId;
  private long userId;
  private boolean isCurrentUser;
  private int status;
  public int getStatus() {
    return status;
  }
  @Override
  public void bindView(MomentItem data_){
    this.data = data_;
    llMomentViewContainer.setVisibility(data == null &#63; View.GONE : View.VISIBLE);
    if (data == null) {
      Log.w(TAG, "bindView data == null >> return;");
      return;
    }
    this.user = data.getUser();
    this.moment = data.getMoment();
    this.momentId = moment.getId();
    this.userId = moment.getUserId();
    this.isCurrentUser = APIJSONApplication.getInstance().isCurrentUser(moment.getUserId());
    this.status = data.getMyStatus();
    ImageLoaderUtil.loadImage(ivMomentViewHead, user.getHead());
    tvMomentViewName.setText(StringUtil.getTrimedString(user.getName()));
    tvMomentViewStatus.setText(StringUtil.getTrimedString(data.getStatusString()));
    tvMomentViewStatus.setVisibility(isCurrentUser &#63; View.VISIBLE : View.GONE);
    tvMomentViewContent.setVisibility(StringUtil.isNotEmpty(moment.getContent(), true) &#63; View.VISIBLE : View.GONE);
    tvMomentViewContent.setText(StringUtil.getTrimedString(moment.getContent()));
    tvMomentViewDate.setText(TimeUtil.getSmartDate(moment.getDate()));
    // 圖片
    setPicture(moment.getPictureList());
    // 點贊
    setPraise(data.getIsPraised(), data.getUserList());
    // 評論
    setComment(data.getCommentItemList());
    vMomentViewDivider.setVisibility(llMomentViewPraise.getVisibility() == View.VISIBLE
        && llMomentViewCommentContainer.getVisibility() == View.VISIBLE &#63; View.VISIBLE : View.GONE);
  }
  /**設置點贊
   * @param joined
   * @param list
   */
  private void setPraise(boolean joined, List<User> list) {
    ivMomentViewPraise.setImageResource(joined &#63; R.drawable.praised : R.drawable.praise);
    llMomentViewPraise.setVisibility(list == null || list.isEmpty() &#63; View.GONE : View.VISIBLE);
    if (llMomentViewPraise.getVisibility() == View.VISIBLE) {
      tvMomentViewPraise.setView(list);
    }
  }
  private boolean showComment = true;
  public void setShowComment(boolean showComment) {
    this.showComment = showComment;
  }
  public boolean getShowComment() {
    return showComment;
  }
  public CommentContainerView commentContainerView;
  /**設置評論
   * @param list
   */
  public void setComment(List<CommentItem> list) {
    llMomentViewCommentContainer.setVisibility(showComment == false || list == null || list.isEmpty()
        &#63; View.GONE : View.VISIBLE);
    if (llMomentViewCommentContainer.getVisibility() != View.VISIBLE) {
      Log.i(TAG, "setComment llMomentViewCommentContainer.getVisibility() != View.VISIBLE >> return;");
      return;
    }
    if (commentContainerView == null) {
      commentContainerView = new CommentContainerView(context, resources);
      llMomentViewCommentContainer.removeAllViews();
      llMomentViewCommentContainer.addView(commentContainerView.createView(inflater));
      commentContainerView.setOnCommentClickListener(new OnCommentClickListener() {
        @Override
        public void onCommentClick(CommentItem item, int position, int index, boolean isLong) {
          toComment(item, true);
        }
      });
      commentContainerView.tvCommentContainerViewMore.setOnClickListener(this);
      commentContainerView.setMaxShowCount(5);
    }
    commentContainerView.bindView(list);
  }
  private GridAdapter adapter;
  /**設置圖片
   * @param pictureList
   */
  private void setPicture(List<String> pictureList) {
    List<Entry<String, String>> keyValueList = new ArrayList<Entry<String, String>>();
    if (pictureList != null) {
      for (String picture : pictureList) {
        keyValueList.add(new Entry<String, String>(picture, null));
      }
    }
    int pictureNum = keyValueList.size();
    gvMomentView.setVisibility(pictureNum <= 0 &#63; View.GONE : View.VISIBLE);
    if (pictureNum <= 0) {
      Log.i(TAG, "setList pictureNum <= 0 >> lvModel.setAdapter(null); return;");
      adapter = null;
      gvMomentView.setAdapter(null);
      return;
    }
    gvMomentView.setNumColumns(pictureNum <= 1 &#63; 1 : 3);
    if (adapter == null) {
      adapter = new GridAdapter(context).setHasName(false);
      gvMomentView.setAdapter(adapter);
    }
    adapter.refresh(keyValueList);
    gvMomentView.setOnItemClickListener(this);
    final int gridViewHeight = (int) (ScreenUtil.getScreenSize(context)[0]
        - convertView.getPaddingLeft() - convertView.getPaddingRight()
        - getDimension(R.dimen.moment_view_head_width));
    try {
      if (pictureNum >= 7) {
        gvMomentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, gridViewHeight));
      } else if (pictureNum >= 4) {
        gvMomentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, (gridViewHeight*2)/3));
      } else if (pictureNum >= 2) {
        gvMomentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, gridViewHeight / 3));
      } else {
        gvMomentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
      }
    } catch (Exception e) {
      Log.e(TAG, " setPictureGrid try int gridViewHeight;...>> catch" + e.getMessage());
    }
  }
  /**跳轉到所有評論界面
   * @param isToComment
   */
  private void toComment(boolean isToComment) {
    toComment(null, isToComment);
  }
  /**跳轉到所有評論界面
   * @param commentItem
   * @param isToComment comment有效時為true
   */
  private void toComment(CommentItem commentItem, boolean isToComment) {
    if (commentItem == null) {
      commentItem = new CommentItem();
    }
    toActivity(MomentActivity.createIntent(context, momentId, isToComment
        , commentItem.getId(), commentItem.getUser().getId(), commentItem.getUser().getName()));
  }
  //UI顯示區(操作UI,但不存在數據獲取或處理代碼,也不存在事件監聽代碼)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  //Data數據區(存在數據獲取或處理代碼,但不存在事件監聽代碼)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  @Override
  public MomentItem getData() {//bindView(null)不會使data == null
    return llMomentViewContainer.getVisibility() == View.VISIBLE &#63; data : null;
  }
  /**判斷是否已登錄,如果未登錄則彈出登錄界面
   * @return
   */
  private boolean isLoggedIn() {
    boolean isLoggedIn = APIJSONApplication.getInstance().isLoggedIn();
    if (isLoggedIn == false) {
      context.startActivity(LoginActivity.createIntent(context));
      context.overridePendingTransition(R.anim.bottom_push_in, R.anim.hold);
    }
    return isLoggedIn;
  }
  /**點贊
   * @param toPraise
   */
  public void praise(boolean toPraise) {
    if (data == null || toPraise == data.getIsPraised()) {
      Log.e(TAG, "praiseWork toPraise == moment.getIsPraise() >> return;");
      return;
    }
    //    setPraise(toPraise, data.getPraiseCount() + (toPraise &#63; 1 : -1));
    HttpRequest.praiseMoment(momentId, toPraise, toPraise &#63; HTTP_PRAISE : HTTP_CANCEL_PRAISE, this);
  }
  //Data數據區(存在數據獲取或處理代碼,但不存在事件監聽代碼)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  //Event事件監聽區(只要存在事件監聽代碼就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  @Override
  public void onDialogButtonClick(int requestCode, boolean isPositive) {
    if (isPositive && data != null) {
      data.setMyStatus(MomentItem.STATUS_DELETING);
      bindView(data);
      HttpRequest.deleteMoment(moment.getId(), HTTP_DELETE, this);
    }
  }
  public static final int HTTP_PRAISE = 1;
  public static final int HTTP_CANCEL_PRAISE = 2;
  public static final int HTTP_DELETE = 3;
  @Override
  public void onHttpResponse(int requestCode, String result, Exception e) {
    if (data == null) {
      Log.e(TAG, "onHttpResponse data == null >> return;");
      return;
    }
    JSONResponse response = new JSONResponse(result);
    JSONResponse response2 = response.getJSONResponse(Moment.class.getSimpleName());
    boolean isSucceed = JSONResponse.isSucceed(response2);
    switch (requestCode) {
    case HTTP_PRAISE:
    case HTTP_CANCEL_PRAISE:
      if (isSucceed) {
        data.setIsPraised(requestCode == HTTP_PRAISE);
        bindView(data);
      } else {
        showShortToast((requestCode == HTTP_PRAISE &#63; "點贊" : "取消點贊") + "失敗,請檢查網絡后重試");
      }
      break;
    case HTTP_DELETE:
      showShortToast(isSucceed &#63; R.string.delete_succeed : R.string.delete_failed);
      //只對adapter.getCount()有影響。目前是隱藏的,不需要通知,也不需要刷新adapter,用戶手動刷新后自然就更新了。
      if (isSucceed) {
        bindView(null);
        status = MomentItem.STATUS_DELETED;
        if (onDataChangedListener != null) {
          onDataChangedListener.onDataChanged();
        }
        CacheManager.getInstance().remove(MomentItem.class, "" + momentId);
      } else {
        data.setMyStatus(MomentItem.STATUS_NORMAL);
        bindView(data);
      }
      break;
    }
  }
  @Override
  public void onClick(View v) {
    if (data == null) {
      return;
    }
    if (status == MomentItem.STATUS_PUBLISHING) {
      showShortToast(R.string.publishing);
      return;
    }
    switch (v.getId()) {
    case R.id.ivMomentViewHead:
    case R.id.tvMomentViewName:
      toActivity(UserActivity.createIntent(context, userId));
      break;
    case R.id.tvMomentViewStatus:
      if (status == MomentItem.STATUS_NORMAL) {
        new AlertDialog(context, "", "刪除動態", true, 0, this).show();
      }
      break;
    case R.id.tvMomentViewContent:
    case R.id.tvCommentContainerViewMore:
      toComment(false);
      break;
    case R.id.tvMomentViewPraise:
    case R.id.llMomentViewPraise:
      toActivity(UserListActivity.createIntent(context, data.getPraiseUserIdList())
          .putExtra(UserListActivity.INTENT_TITLE, "點贊的人"));
      break;
    default:
      if (isLoggedIn() == false) {
        return;
      }
      switch (v.getId()) {
      case R.id.ivMomentViewPraise:
        praise(! data.getIsPraised());
        break;
      case R.id.ivMomentViewComment:
        toComment(true);
        break;
      default:
        break;
      }
      break;
    }
  }
  @Override
  public void onItemClick(AdapterView<&#63;> parent, View view, int position, long id) {
    if (status == MomentItem.STATUS_PUBLISHING) {
      showShortToast(R.string.publishing);
      return;
    }
    if (onPictureClickListener != null) {
      onPictureClickListener.onClickPicture(this.position, this, position);
    } else {
      toActivity(WebViewActivity.createIntent(context, null
          , adapter == null &#63; null : adapter.getItem(position).getKey()));
    }
  }
  //Event事件監聽區(只要存在事件監聽代碼就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}

moment_view.xml

<&#63;xml version="1.0" encoding="utf-8"&#63;>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  
  android:descendantFocusability="blocksDescendants" >
  <LinearLayout
    android:id="@+id/llMomentViewContainer"
    
    android:background="@color/white"
    android:gravity="top"
    android:padding="10dp" >
    <RelativeLayout
      android:id="@+id/rlMomentViewItemHead"
      android:layout_width="@dimen/moment_view_head_width"
      android:layout_height="@dimen/moment_view_head_height"
      android:paddingRight="@dimen/moment_view_head_padding_right" >
      <ImageView
        android:background="@color/alpha_3"
        android:id="@+id/ivMomentViewHead"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop" />
    </RelativeLayout>
    <LinearLayout
      
      android:layout_below="@+id/rlMomentViewItemHead"
      android:layout_toRightOf="@+id/rlMomentViewItemHead"
      android:gravity="left" >
      <LinearLayout
        
        android:layout_height="match_parent" >
        <TextView
          android:id="@+id/tvMomentViewName"
          
          android:layout_width="match_parent"
          android:layout_weight="1"
          android:background="@drawable/bg_item_to_alpha"
          android:gravity="left"
          android:text="Name" />
        <TextView
          android:id="@+id/tvMomentViewStatus"
          
          android:background="@drawable/bg_item_to_alpha"
          android:text="發布中" />
      </LinearLayout>
      <TextView
        android:id="@+id/tvMomentViewContent"
        
        android:layout_width="match_parent"
        android:layout_marginTop="5dp"
        android:background="@drawable/bg_item_to_alpha"
        android:gravity="left|top"
        android:maxLines="8"
        android:paddingBottom="5dp"
        android:text="This is a content..." />
      <apijson.demo.client.view.EmptyEventGridView
        android:id="@+id/gvMomentView"
        
        android:focusable="false"
        android:horizontalSpacing="4dp"
        android:listSelector="@drawable/bg_item_to_alpha"
        android:numColumns="3"
        android:paddingTop="4dp"
        android:scrollbars="none"
        android:stretchMode="columnWidth"
        android:verticalSpacing="4dp" />
      <LinearLayout
        
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp" >
        <TextView
          android:id="@+id/tvMomentViewDate"
          
          android:layout_width="match_parent"
          android:layout_weight="1"
          android:gravity="left"
          android:text="2015年12月" />
        <ImageView
          android:id="@+id/ivMomentViewPraise"
          
          android:layout_marginRight="18dp"
          android:background="@drawable/bg_item_to_alpha"
          android:src="@drawable/praise" />
        <ImageView
          android:id="@+id/ivMomentViewComment"
          
          android:background="@drawable/bg_item_to_alpha"
          android:src="@drawable/comment" />
      </LinearLayout>
      <LinearLayout
        
        android:layout_marginTop="5dp"
        android:background="@color/alpha_1"
        android:paddingLeft="8dp"
        android:paddingRight="8dp" >
        <LinearLayout
          android:id="@+id/llMomentViewPraise"
          
          android:layout_height="wrap_content"
          android:layout_marginBottom="4dp"
          android:layout_marginTop="4dp"
          android:background="@drawable/bg_item_to_alpha"
          android:gravity="top" >
          <ImageView
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:scaleType="fitXY"
            android:src="@drawable/praise" />
          <apijson.demo.client.view.PraiseTextView
            android:id="@+id/tvMomentViewPraise"
            
            android:background="@drawable/bg_item_to_alpha"
            android:gravity="left|top"
            android:lineSpacingExtra="4dp"
            android:text="等覺得很贊" />
        </LinearLayout>
        <View
          android:id="@+id/vMomentViewDivider"
           />
        <LinearLayout
          android:id="@+id/llMomentViewCommentContainer"
          
          android:paddingBottom="4dp"
          android:paddingTop="4dp" >
        </LinearLayout>
      </LinearLayout>
    </LinearLayout>
  </LinearLayout>
</RelativeLayout>

由于這個項目使用了ZBLibrary快速開發框架,所以實現仿QQ空間和微信朋友圈的這種復雜界面只用了極少的代碼,并且高解耦、高復用、高靈活。

服務端是用APIJSON(Server)工程快速搭建的,客戶端App和服務端通過APIJSON-JSON傳輸結構協議通信,非常方便靈活,省去了大量的接口和文檔!

今年RxJava特別火,在北京市場幾乎是必備技能,所以我還把這個項目做了個RxJava版本,歡迎交流和指教。

實現UI的Java類:

MomentListFragment       395行       動態列表的獲取和顯示
MomentActivity         616行       動態和評論列表的獲取、顯示和交互(評論和刪除評論等)
MomentAdapter          67行        動態列表的顯示
CommentAdapter         82行        評論列表的顯示
MomentView           495行       動態的顯示和交互(各種跳轉、點贊、刪除等)
EmptyEventGridView       56行        動態里圖片的顯示和交互(觸摸空白處傳遞觸摸事件到內層View)
PraiseTextView         129行       動態里點贊用戶的顯示和交互(點擊姓名跳到個人詳情,點擊整體跳到點贊的用戶列表界面)
CommentView           153行       一級評論(頭像、姓名、內容)的顯示和交互(回復、刪除等),添加二級評論列表
CommentContainerView      172行       二級評論列表的顯示和交互(查看全部等)
CommentTextView         122行       二級評論(姓名、內容)的顯示和交互(回復、刪除等)

實現UI的XML布局:

moment_activity         47行        動態和評論列表的顯示
moment_view           148行       動態的顯示
comment_view          87行        一級評論(頭像、姓名、內容)的顯示
comment_container_view     20行        二級評論列表的顯示
comment_item          10行        二級評論(姓名、內容)的顯示

為什么沒有實現MomentListFragment對應的XML布局?

因為MomentListFragment繼承BaseHttpListFragment,內部用XListView作為缺省列表View,所以可以不用自己實現了。

實現數據獲取、提交和處理的Java類:

HttpRequest           +175行       數據的獲取和提交(getMoment,...,deleteComment)
CommentUtil           140行       單層評論和和二級評論的處理
Comment             56行        評論數據
CommentItem           99行        評論的顯示和交互數據
Moment             43行        動態數據
MomentItem           272行       動態的顯示和交互數據
User              103行       用戶數據

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注創新互聯行業資訊頻道,感謝您對創新互聯的支持。

分享名稱:如何在Android應用中實現一個動態界面分享功能
當前網址:http://m.2m8n56k.cn/article18/ggdgdp.html

成都網站建設公司_創新互聯,為您提供Google、網站內鏈、做網站建站公司、企業建站、品牌網站建設

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

外貿網站制作
主站蜘蛛池模板: 这里只有精品国产 | 久久手机免费视频 | 国产a一级| 人与禽的免费一级毛片 | 欧美性精品| 国产自产v一区二区三区c | 日韩中文字幕在线亚洲一区 | 香蕉久久夜色精品国产 | 99热.com| 玖玖色视频 | 中国一级毛片欧美一级毛片 | 黄色网址在线免费观看 | 成人国产在线视频在线观看 | 日本污污网站 | 小草青青神马影院 | 性欧美videofree中文字幕 | 中文字幕一级片 | www亚洲免费 | 亚洲欧美在线观看播放 | 成人精品视频在线 | 精品国产午夜肉伦伦影院 | 亚洲国产精品久久综合 | 久久最新视频 | 欧美一级高清片欧美国产欧美 | 国产成人午夜性a一级毛片 国产成人午夜性视频影院 国产成人香蕉久久久久 | 亚洲国产欧美日韩第一香蕉 | 男女牲高爱潮免费视频男女 | 精品午夜国产在线观看不卡 | 亚洲国产专区 | 国产一级在线现免费观看 | 日韩在线小视频 | 国产三级a三级三级 | 波多野结衣被强在线视频 | 亚欧在线视频 | 国产成年人在线观看 | 国产亚洲欧洲精品 | 免费一级欧美大片久久网 | 免费看一级欧美毛片视频 | 成人午夜影院在线观看 | 偷窥女厕国产在线视频 | 手机看片久久国产免费不卡 |