Android仿QQ、微信聊天界面长按提示框效果
作者:伪文艺大叔 发布时间:2023-06-11 14:04:32
先来看看效果图
如何使用
示例代码
PromptViewHelper pvHelper = new PromptViewHelper(mActivity);
pvHelper.setPromptViewManager(new ChatPromptViewManager(mActivity));
pvHelper.addPrompt(holder.itemView.findViewById(R.id.textview_content));
使用起来还是很简单的
首先new一个PromptViewHelper
类,然后设置一个提示view管理器,最后调用addPrompt
方法添加view,此 view就是要添加提示框的view。
实现思路
通过使用QQ,微信这个功能,感觉提示框使用PopupWindow
应该是可以满足需求的。
所以大体的思路就是:
1、View加载成功的时候给它添加长按事件
2、用户长按的时候new一个PopupWindow
,并且显示它,并且设置点击外部区域可以消失
架构
为了让上层调用简单,方便,我打算把提示框View封装到一个类中,这个类包括:初始方法,绑定数据,添加事件等等;基于这样的考虑,首先定义一个抽象类,然后让具体的实现类来实现相应的方法,我们先来看看这个抽象类。
public static abstract class PromptViewManager {
private View promptView;
protected Activity activity;
private String[] dataArray;
private Location location;
public OnItemClickListener onItemClickListener;
public PromptViewManager(Activity activity, String[] dataArray, Location location) {
this.activity = activity;
this.dataArray = dataArray;
this.location = location;
init();
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void init() {
promptView = inflateView();
bindData(promptView, dataArray);
}
public abstract View inflateView();
public abstract void bindData(View view, String[] dataArray);
public View getPromptView() {
return promptView;
}
public Location getLocation() {
return location;
}
}
注意:在一个抽象类中有一个Location对象的属性,这个Location是做什么的个,因为我们在显示这个提示框View的时候会要考虑它显示的位置,这个Location是个枚举对象,它里面就包括了一些位置的信息;
public enum Location {
TOP_LEFT(1), TOP_CENTER(2), TOP_RIGHT(3),
BOTTOM_LEFT(4), BOTTOM_CENTER(5), BOTTOM_RIGHT(6);
ICalculateLocation calculateLocation;
private Location(int type) {
switch (type) {
case 1:
calculateLocation = ICalculateLocation 实现类
break;
case 2:
calculateLocation = ICalculateLocation 实现类
break;
TODO
}
}
这个枚举对象里面包含了6种位置显示类型,然后在构造方法里面根据type类型会实例化一个ICalculateLocation
对象,ICalculateLocation
是什么呢?
public interface ICalculateLocation {
int[] calculate(int[] srcViewLocation, View srcView, View promptView);
}
它是一个接口,提供了一个calculate
方法来计算提示框View的x,y坐标,我们通过实现这个接口来计算不同位置的坐标。
到这,大体的架构已经出来了;首先我们定义一个PromtpViewManager
管理器来来实现提示框View的加载,绑定数据,添加事件,然后通过设置的Location枚举来实现不同的计算类,计算出不同位置的坐标,然后在显示的时候new一个PopupWindow
,通过PromtpViewManager
得到提示框View设置给PopupWindow
,再通过PromtpViewManager
得到Location枚举得到计算坐标的类,调用calculate方法得到x,y坐标,然后通过PopupWindow
的showAtLocation
方法来显示PopupWindow
提示框。
具体实现
首先实现一个PromtpViewManager
管理类
public class ChatPromptViewManager extends PromptViewHelper.PromptViewManager {
public ChatPromptViewManager(Activity activity, String[] dataArray,
Location location) {
super(activity, dataArray, location);
}
public ChatPromptViewManager(Activity activity) {
this(activity, new String[]{"复制", "粘贴", "转发"}, Location.TOP_LEFT);
}
public ChatPromptViewManager(Activity activity, Location location) {
this(activity, new String[]{"复制", "粘贴", "转发"}, location);
}
@Override
public View inflateView() {
return new PromptView(activity);
}
@Override
public void bindData(View view, String[] dataArray) {
if(view instanceof PromptView) {
PromptView promptView = (PromptView) view;
promptView.setContentArray(dataArray);
promptView.setOnItemClickListener(new PromptView.OnItemClickListener() {
@Override
public void onItemClick(int position) {
if(onItemClickListener != null)
onItemClickListener.onItemClick(position);
}
});
}
}}
实例化View,绑定数据,添加事件都已经完成了,下面就要计算View显示的坐标了,我这边实现了几个方法,贴出一个来看看,如果大家对位置有自己的需求可以自己来实现一个类复写方法。
public class TopCenterLocation implements ICalculateLocation {
@Override
public int[] calculate(int[] srcViewLocation, View srcView, View promptView) {
int[] location = new int[2];
int offset = (promptView.getWidth() - srcView.getWidth()) / 2;
location[0] = srcViewLocation[0] - offset;
location[1] = srcViewLocation[1] - promptView.getHeight();
return location;
}}
总结


猜你喜欢
- 在使用SpringBoot做接口访问如何做接口的限流,这里我们可以使用google的Guava包来实现,当然我们也可以自己实现限流,Guav
- 简单了解计算机为什么要采用二进制表示信息:因为计算机作为一种电子计算机工具,是由大量的电子器件组成的,在这些电子器件中,电路的通断,电位的高
- 一、JVM 内存模型根据 JVM 规范,JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。1、虚拟机栈:每个线程有一个
- 1.前言在Mybatis中需要创建的配置文件有sqlMapconfig.xml,映射文件xxxMapper.xml,而这些文件在idea中并
- 引言使用标准框架验证Java bean的基础知识 - JSR 380,也称为Bean Validation 2.0。当然,验证用户输入在大多
- 1,如今NestedScrolling运用到很多地方了,要想好看一点的滑动变换,基本上就是使用这个来完成的,让我们来简单的了解一下。2,Ne
- 五一期间原计划是写两篇文章,看一本技术类书籍,结果这五天由于自律性过于差,禁不住各种诱惑,我连电脑都没打开过,计划完美宣告失败。所以在这能看
- springboot配置mysql数据库spring.datasource.url报错spring.datasource.url=jdbc:
- Java 向上转型和向下转型的详解转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父
- MVC注解式开发即处理器基于注解的类开发, 对于每一个定义的处理器, 无需在xml中注册.只需在代码中通过对类与方法的注解, 即可完成注册.
- 在实际开发中,我们经常会需要在页面跳转的时候携带路由参数,典型的例子就是从列表到详情页的时候,需要携带详情的 id,以便详情页获取对应的数据
- 1.背景选择器(位于res/drawable/,使用方法:android:background=”@drawable/XXX”) <?
- 提到数组大家肯定不会陌生,但我们也知道数组有个缺点就是在创建时就确定了长度,之后就不能更改长度。所以Java官方向我们提供了ArrayLis
- 下文笔者讲述java中String.intern()方法的功能简介说明,如下所示:String.intern原理String.intern(
- 一、添加插件apply plugin: 'maven-publish'二、添加如下配置//打包源码task sourceJa
- Main方法如下:static void Main(string[] args){ dynamic st
- itext生成PDF设置页眉页脚的实例详解实例代码:/** * ITextTest * iText生成PDF加入列表,注释等内容,同时设
- 这篇文章主要介绍了SpringBoot如何读取war包jar包和Resource资源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具
- 概述异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。异常提供了一种把程序控制权从某个部
- 本文实例为大家分享了java实现顺时针打印矩阵的具体代码,供大家参考,具体内容如下题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每