首页 > 系统 > Android > 正文

Android 仿微信朋友圈点赞和评论弹出框功能

2019-12-12 04:39:26
字体:
来源:转载
供稿:网友

贡献/下载源码:https://github.com/mmlovesyy/PopupWindowDemo

本文简单模仿微信朋友圈的点赞和评论弹出框,布局等细节请忽略,着重实现弹出框、发评论,及弹出位置的控制。

1. 微信弹出框

微信朋友圈的点赞和评论功能,有2个组成部分:

点击左下角的“更多”按钮,弹出对话框;

点击评论,弹出输入框,添加评论并在页面中实时显示;

 

微信朋友圈点赞和评论功能

2. 实际效果

本文将建一个 ListView,在其 Item 中简单模仿微信的布局,然后着重实现弹出窗,并能发评论,忽略具体布局细节。具体效果如下:

 

3. 知识点清单

ListView

自定义 Adapter,重写 getView()方法;

PopupWindow

弹出框使用PopupWindow实现,这是点赞和评论的载体,具体要涉及 PopupWindow 点击非窗口位置和再次点击消失以及显示位置的问题(根据相应更多按钮的位置确定 PopupWindow 的显示位置,关于 PopupWindow 的显示位置,可以参考我的另一篇文章 Android PopupWindow 的显示位置);

LayoutInflater

使用LayoutInflater 动态加载PopupWindow 的布局,关于 LayoutInflater 的更多知识,参见我的另一篇博客 Android LayoutInflater ;

Activity 和 Item 的双向通信

通过自定义 OnCommentListener() 来实现 MainActivity(具体来说是屏幕底部评论框中的输入的内容)和 ItemView(动态的获得上述输入的评论内容并展示在该ItemView 中) 的通信,更多知识参见我的另一篇博客《 燕过留声:由 Activity 和 Fragment 的通信方法想到的》;

自定义控件

ListView 中的每个 Item 是一个自定义的 ItemView,记得要重写构造方法,否则会抛出 Android.view.InflateException 异常;

如果想实现微信评论那样用户名和内容回复文字字体颜色不同,而且点击评论用户名触发页面跳转等功能,请参见 《布局优化技巧笔记》 之 ClickableSpan 章节;

4. 美工素材

由于 .apk 本质上是个压缩包,我们可以通过解压得到该 .apk 文件的图片素材和布局文件,更多获得素材的方法参见我的另一篇博文 如何获得Android素材图片。通过这种方式得到颜色、更多按钮的样式等素材,仅供学习之用,请勿做侵犯版权之事。尊重知识版权既是大势所趋,也是终将使每个开发者受益的事。

 

文件夹r里存放图片

 

找到更多按钮

5. 关键代码

开发环境:Android Studio 1.4.1 for Mac + ADT 21 + JDK 1.8.0。

MainAcitivity.Java

package main.zhaizu.com.popupwindowdemo;import android.content.Context;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.EditText;import android.widget.ListView;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import main.zhaizu.com.popupwindowdemo.model.Comment;import main.zhaizu.com.popupwindowdemo.model.Item;import main.zhaizu.com.popupwindowdemo.ui.ItemView;public class MainActivity extends AppCompatActivity {private ListView mListView;private View mCommentView;private MyAdapter myAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mListView = (ListView) findViewById(R.id.listview);myAdapter = new MyAdapter(this, getData());mListView.setAdapter(myAdapter);mCommentView = findViewById(R.id.comment_view);}// build dataprivate ArrayList<Item> getData() {int ITEM_COUNT = 20;ArrayList<Item> data = new ArrayList<>();data.add(new Item(R.drawable.xiaona, "薄荷栗", "我学过跆拳道,都给我跪下唱征服", "昨天"));data.add(new Item(R.drawable.xueyan, "欣然", "走遍天涯海角,唯有我家风景最好,啊哈哈", "昨天"));data.add(new Item(R.drawable.leishao, "陈磊_CL", "老子以后要当行长的,都来找我借钱吧,now", "昨天"));data.add(new Item(R.drawable.yuhong, "永恒依然", "房子车子都到碗里来", "昨天"));data.add(new Item(R.drawable.lanshan, "蓝珊", "你们这群傻×,我笑而不语", "昨天"));return data;}// custom adapterprivate class MyAdapter extends BaseAdapter implements ItemView.OnCommentListener {private Context context;private ArrayList<Item> mData;private Map<Integer, ItemView> mCachedViews = new HashMap<>();public MyAdapter(Context context, ArrayList<Item> mData) {this.context = context;this.mData = mData;}@Overridepublic int getCount() {return mData.size();}@Overridepublic Object getItem(int position) {return mData.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view;if (convertView != null) {view = convertView;} else {LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);view = inflater.inflate(R.layout.listview_item, null, false);}if (view instanceof ItemView) {Item data = (Item) getItem(position);((ItemView) view).setData(data);((ItemView) view).setPosition(position);((ItemView) view).setCommentListener(this);cacheView(position, (ItemView) view);}return view;}@Overridepublic void onComment(int position) {showCommentView(position);}private void cacheView(int position, ItemView view) {Iterator<Map.Entry<Integer, ItemView>> entries = mCachedViews.entrySet().iterator();while (entries.hasNext()) {Map.Entry<Integer, ItemView> entry = entries.next();if (entry.getValue() == view && entry.getKey() != position) {mCachedViews.remove(entry.getKey());break;}}mCachedViews.put(position, view);}private void showCommentView(final int position) {mCommentView.setVisibility(View.VISIBLE);mCommentView.findViewById(R.id.submit).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {EditText et = (EditText) mCommentView.findViewById(R.id.edit);String s = et.getText().toString();if (!TextUtils.isEmpty(s)) {// update modelComment comment = new Comment(s);mData.get(position).getComments().add(comment);// update view maybeItemView itemView = mCachedViews.get(position);if (itemView != null && position == itemView.getPosition()) {itemView.addComment();}et.setText("");mCommentView.setVisibility(View.GONE);}}});}}}

ItemView.java

package main.zhaizu.com.popupwindowdemo.ui;import android.content.Context;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.PopupWindow;import android.widget.TextView;import main.zhaizu.com.popupwindowdemo.R;import main.zhaizu.com.popupwindowdemo.model.Comment;import main.zhaizu.com.popupwindowdemo.model.Item;/*** Created by cmm on 15/10/31.*/public class ItemView extends LinearLayout implements View.OnClickListener {private int mPosition;private Item mData;private ImageView mPortraitView;private TextView mUserNameView;private TextView mContentView;private TextView mCreatedAtView;private LinearLayout mCommentLayout;private View mMoreView;private PopupWindow mMorePopupWindow;private int mShowMorePopupWindowWidth;private int mShowMorePopupWindowHeight;private OnCommentListener mCommentListener;public ItemView(Context context) {super(context);}public ItemView(Context context, AttributeSet attrs) {super(context, attrs);}public interface OnCommentListener {void onComment(int position);}@Overrideprotected void onFinishInflate() {super.onFinishInflate();mPortraitView = (ImageView) findViewById(R.id.portrait);mUserNameView = (TextView) findViewById(R.id.nick_name);mContentView = (TextView) findViewById(R.id.content);mCreatedAtView = (TextView) findViewById(R.id.created_at);mCommentLayout = (LinearLayout) findViewById(R.id.comment_layout);mMoreView = findViewById(R.id.more_btn);}public void setPosition(int mPosition) {this.mPosition = mPosition;}public void setCommentListener(OnCommentListener l) {this.mCommentListener = l;}public void setData(Item data) {mData = data;mPortraitView.setImageResource(data.getPortraitId());mUserNameView.setText(data.getNickName());mContentView.setText(data.getContent());updateComment();mMoreView.setOnClickListener(this);}/*** 弹出点赞和评论框** @param moreBtnView*/private void showMore(View moreBtnView) {if (mMorePopupWindow == null) {LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);View content = li.inflate(R.layout.layout_more, null, false);mMorePopupWindow = new PopupWindow(content, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);mMorePopupWindow.setBackgroundDrawable(new BitmapDrawable());mMorePopupWindow.setOutsideTouchable(true);mMorePopupWindow.setTouchable(true);content.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);mShowMorePopupWindowWidth = content.getMeasuredWidth();mShowMorePopupWindowHeight = content.getMeasuredHeight();View parent = mMorePopupWindow.getContentView();TextView like = (TextView) parent.findViewById(R.id.like);TextView comment = (TextView) parent.findViewById(R.id.comment);// 点赞的监听器comment.setOnClickListener(this);}if (mMorePopupWindow.isShowing()) {mMorePopupWindow.dismiss();} else {int heightMoreBtnView = moreBtnView.getHeight();mMorePopupWindow.showAsDropDown(moreBtnView, -mShowMorePopupWindowWidth,-(mShowMorePopupWindowHeight + heightMoreBtnView) / 2);}}private void updateComment() {if (mData.hasComment()) {mCommentLayout.removeAllViews();mCommentLayout.setVisibility(View.VISIBLE);for (Comment c : mData.getComments()) {TextView t = new TextView(getContext());t.setLayoutParams(new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)));t.setBackgroundColor(getResources().getColor(R.color.colorCommentLayoutBg));t.setTextSize(16);t.setPadding(5, 2, 0, 3);t.setLineSpacing(3, (float) 1.5);t.setText(c.getComment());mCommentLayout.addView(t);}} else {mCommentLayout.setVisibility(View.GONE);}}@Overridepublic void onClick(View v) {int id = v.getId();if (id == R.id.more_btn) {showMore(v);} else if (id == R.id.comment) {if (mCommentListener != null) {mCommentListener.onComment(mPosition);if (mMorePopupWindow != null && mMorePopupWindow.isShowing()) {mMorePopupWindow.dismiss();}}}}public int getPosition() {return mPosition;}public void addComment() {updateComment();}}

以上所述是小编给大家介绍的Android 仿微信朋友圈点赞和评论弹出框功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表