Android QQ 공간 동적 인터페이스 공유 기능 모방
아주 적은 코드 로 동적 상세 정보 와 2 급 댓 글 의 데이터 획득 과 처리,UI 디 스 플레이 와 상호작용 을 실현 하고 높 은 디 스 플레이,높 은 재 활용,높 은 유연성 을 실현 합 니 다.
동적 목록 인터페이스 Moment ListFragment 는 드 롭 다운 리 셋 과 업 로드,퍼 지 검색 을 지원 하 며 빠 른 미끄럼 을 반복 하 는 것 이 유창 합 니 다.
캐 시 메커니즘 은 데 이 터 를 시작 인터페이스 후 순식간에 불 러 올 수 있 도록 합 니 다.
동적 상세 인터페이스 Moment Activity 지원(취소)좋아요 누 르 기,댓 글 삭제,이름 누 르 고 개인 정보 로 건 너 뛰 기 등.
한 장의 그림 만 있 을 때 그림 이 확대 되 어 표시 되 고 한 장 이 넘 으 면 구 궁 격 으로 표시 된다.
사용 하 는 Comment Container View 와 Moment View 는 모두 독립 된 구성 요소 로 단독으로 사용 할 수도 있 고 ListView 나 다른 View Group 에 추가 할 수도 있 습 니 다.
댓 글 ContainerView 재 활용
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() ? 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 ? :
*/
public void setMaxShowCount(int maxShowCount) {
this.maxShowCount = maxShowCount;
}
/**
* @param list
*/
public void setComment(List<CommentItem> list) {
int count = list == null ? 0 : list.size();
boolean showMore = maxShowCount > 0 && count > maxShowCount;
tvCommentContainerViewMore.setVisibility(showMore ? View.VISIBLE : View.GONE);
llCommentContainerViewContainer.removeAllViews();
llCommentContainerViewContainer.setVisibility(count <= 0 ? 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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ll_vertical_match_wrap" >
<LinearLayout
android:id="@+id/llCommentContainerViewContainer"
style="@style/ll_vertical_match_wrap" >
</LinearLayout>
<TextView
android:id="@+id/tvCommentContainerViewMore"
style="@style/text_small_blue"
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 재 활용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 ? 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 ? View.VISIBLE : View.GONE);
tvMomentViewContent.setVisibility(StringUtil.isNotEmpty(moment.getContent(), true) ? 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 ? View.VISIBLE : View.GONE);
}
/**
* @param joined
* @param list
*/
private void setPraise(boolean joined, List<User> list) {
ivMomentViewPraise.setImageResource(joined ? R.drawable.praised : R.drawable.praise);
llMomentViewPraise.setVisibility(list == null || list.isEmpty() ? 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()
? 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 ? 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 ? 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 ? 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 ? 1 : -1));
HttpRequest.praiseMoment(momentId, toPraise, toPraise ? 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 ? " " : " ") + " , ");
}
break;
case HTTP_DELETE:
showShortToast(isSucceed ? 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<?> 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 ? null : adapter.getItem(position).getKey()));
}
}
//Event ( )>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}
moment_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/match_wrap"
android:descendantFocusability="blocksDescendants" >
<LinearLayout
android:id="@+id/llMomentViewContainer"
style="@style/ll_horizontal_match_wrap"
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
style="@style/ll_vertical_match_wrap"
android:layout_below="@+id/rlMomentViewItemHead"
android:layout_toRightOf="@+id/rlMomentViewItemHead"
android:gravity="left" >
<LinearLayout
style="@style/ll_horizontal_match_wrap"
android:layout_height="match_parent" >
<TextView
android:id="@+id/tvMomentViewName"
style="@style/text_small_blue"
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"
style="@style/text_small_blue"
android:background="@drawable/bg_item_to_alpha"
android:text=" " />
</LinearLayout>
<TextView
android:id="@+id/tvMomentViewContent"
style="@style/text_small_black"
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"
style="@style/wrap_wrap"
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
style="@style/ll_horizontal_match_wrap"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" >
<TextView
android:id="@+id/tvMomentViewDate"
style="@style/text_small_black"
android:layout_width="match_parent"
android:layout_weight="1"
android:gravity="left"
android:text="2015 12 " />
<ImageView
android:id="@+id/ivMomentViewPraise"
style="@style/img_btn"
android:layout_marginRight="18dp"
android:background="@drawable/bg_item_to_alpha"
android:src="@drawable/praise" />
<ImageView
android:id="@+id/ivMomentViewComment"
style="@style/img_btn"
android:background="@drawable/bg_item_to_alpha"
android:src="@drawable/comment" />
</LinearLayout>
<LinearLayout
style="@style/ll_vertical_match_wrap"
android:layout_marginTop="5dp"
android:background="@color/alpha_1"
android:paddingLeft="8dp"
android:paddingRight="8dp" >
<LinearLayout
android:id="@+id/llMomentViewPraise"
style="@style/ll_horizontal_match_wrap"
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"
style="@style/text_small_blue"
android:background="@drawable/bg_item_to_alpha"
android:gravity="left|top"
android:lineSpacingExtra="4dp"
android:text=" " />
</LinearLayout>
<View
android:id="@+id/vMomentViewDivider"
style="@style/divider_horizontal_1px" />
<LinearLayout
android:id="@+id/llMomentViewCommentContainer"
style="@style/ll_vertical_match_wrap"
android:paddingBottom="4dp"
android:paddingTop="4dp" >
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
이 프로젝트 는 ZBLibrary 의 빠 른 개발 프레임 워 크 를 사 용 했 기 때문에 QQ 공간 과 위 챗 모멘트 를 모방 하 는 복잡 한 인터페이스 는 아주 적은 코드 만 사 용 했 고 높 은 디 결합,높 은 재 활용,높 은 유연성 을 가 집 니 다.서버 는 APIJSON(Server)프로젝트 로 신속하게 구축 되 었 습 니 다.클 라 이언 트 App 과 서버 는 APIJSON-JSON 전송 구조 프로 토 콜 을 통 해 통신 되 고 매우 편리 하 며 유연 하 며 대량의 인터페이스 와 문 서 를 절약 합 니 다!
올해 RxJava 는 특히 인기 가 많아 서 베 이 징 시장 에서 거의 필수 기능 이기 때문에 저 는 이 프로젝트 를 RxJava 버 전 으로 만 들 었 습 니 다.교류 와 지 도 를 환영 합 니 다.
UI 구현 자바 클래스:
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 ( 、 )
왜 Moment ListFragment 에 대응 하 는 XML 레이아웃 을 실현 하지 못 했 습 니까?Moment ListFragment 는 BaseHttpListFragment 를 계승 하고 내 부 는 XListView 를 결 성 목록 View 로 사용 하기 때문에 스스로 실현 하지 않 아 도 된다.
데이터 가 져 오기,제출,처 리 를 위 한 자바 클래스:
HttpRequest +175 (getMoment,...,deleteComment)
CommentUtil 140
Comment 56
CommentItem 99
Moment 43
MomentItem 272
User 103
(비고:열거 되 지 않 은 코드 파일 은 동적 과 무관 하거나 APIJSON 또는 ZBLibrary 가 제공 합 니 다.server.model 의 클래스 는 서버 에서 제공 합 니 다)QQ 공간 과 위 챗 모멘트 를 모방 하여 높 은 디 결합 과 높 은 재 활용 이 유연 합 니 다.
테스트 서버 주소:139.196.140.118:8080 다운로드
APIJSONClientApp.apk
원본 및 문서(Star 에 게 주 십시오)
https://github.com/TommyLemon/APIJSON
위 에서 말 한 것 은 소 편 이 여러분 에 게 소개 한 안 드 로 이 드 모 의 QQ 공간 동적 인터페이스 공유 기능 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 저 에 게 메 시 지 를 남 겨 주세요.소 편 은 신속하게 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.