Android开发空间靠右放代码,Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果...

本文主要是介绍Android开发空间靠右放代码,Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们打开QQ空间的时候有个箭头按钮点击之后弹出PopupWindow会根据位置的变化显示在箭头的上方还是下方,比普通的PopupWindow弹在屏幕中间显示好看的多。

先看QQ空间效果图:

1fe809b6c49d62d2bc1fdb2f66fdb63c.pngedd63cf8f14bcd0bea4b1205695767a0.png

e0a1b0830d098a6fe441363bbc485914.png

这个要实现这个效果可以分几步进行

1.第一步自定义PopupWindow,实现如图的样式,这个继承PopupWindow自定义布局很容易实现

2.得到点击按钮的位置,根据位置是否在屏幕的中间的上方还是下方,将PopupWindow显示在控件的上方或者下方

2897382d8bb72635f1403592b4ab5826.png

3.适配问题,因为PopupWindow上面的操作列表是动态的所以要自定义listView

4.动画效果+背景变暗

通过步骤分析,我们就很清晰的了解我们要做什么,话不多说,从第一步开始吧

下面自定义PopupWindow实现效果

1.重写listView,重新计算高度(一般也应用于解决ScrollView嵌套listView只显示一行的问题)

public class MyListView extends ListView {

public MyListView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyListView(Context context) {

super(context);

}

public MyListView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

@Override

public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,

MeasureSpec.AT_MOST));

}

}

2.自定义PopupWindow的布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:gravity="right">

android:id="@+id/arrow_up"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginRight="28dp"

android:src="@drawable/arrow_up_white"

android:visibility="visible"/>

android:id="@+id/lv_list"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:padding="@dimen/normal_margin8"

android:layout_marginTop="-1dp"

android:layout_marginBottom="-1dp"

android:dividerHeight="0dp"

android:layout_marginLeft="@dimen/normal_margin8"

android:layout_marginRight="@dimen/normal_margin8"

android:scrollbars="none"

android:background="@drawable/custom_white"

android:divider="@null">

android:id="@+id/arrow_down"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginRight="28dp"

android:src="@drawable/arrow_down_white"

android:visibility="visible"/>

2.PopupWindow弹出动画以及消失动画

popshow_operation_anim_down.xml

android:fromXScale="0.0"

android:toXScale="1.0"

android:fromYScale="0.0"

android:toYScale="1.0"

android:pivotX="90%"

android:pivotY="0%"

android:fillAfter="false"

android:duration="300" >

popshow_operation_anim_up.xml

android:fromXScale="0.0"

android:toXScale="1.0"

android:fromYScale="0.0"

android:toYScale="1.0"

android:pivotX="90%"

android:pivotY="100%"

android:fillAfter="false"

android:duration="250" >

消失动画是渐隐动画可以自己定义,同理。

3.重写PopupWindow了

public class CustomOperationPopWindow extends PopupWindow {

private Context context;

private View conentView;

private View backgroundView;

private Animation anim_backgroundView;

private MyListView listView;

private TypeSelectPopuAdapter selectAdapter;

ImageView arrow_up, arrow_down;

List typeSelectlist = new ArrayList<>();

int[] location = new int[2];

private OnItemListener onItemListener;

private AdapterView.OnItemClickListener onItemClickListener;

public interface OnItemListener {

public void OnItemListener(int position, TypeSelect typeSelect);

}

;

public void setOnItemMyListener(OnItemListener onItemListener) {

this.onItemListener = onItemListener;

}

public CustomOperationPopWindow(Context context) {

this.context = context;

initView();

}

public CustomOperationPopWindow(Context context, List typeSelectlist) {

this.context = context;

this.typeSelectlist = typeSelectlist;

initView();

}

private void initView() {

this.anim_backgroundView = AnimationUtils.loadAnimation(context, R.anim.alpha_show_anim);

LayoutInflater inflater = (LayoutInflater) context

.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

this.conentView = inflater.inflate(R.layout.view_operation_popupwindow, null);

// 设置SelectPicPopupWindow的View

this.setContentView(conentView);

// 设置SelectPicPopupWindow弹出窗体的宽

this.setWidth(LayoutParams.MATCH_PARENT);

// 设置SelectPicPopupWindow弹出窗体的高

this.setHeight(LayoutParams.WRAP_CONTENT);

// 设置SelectPicPopupWindow弹出窗体可点击

this.setFocusable(true);

this.setOutsideTouchable(true);

// 刷新状态

this.update();

// 实例化一个ColorDrawable颜色为半透明

ColorDrawable dw = new ColorDrawable(0000000000);

// 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作

this.setBackgroundDrawable(dw);

// 设置SelectPicPopupWindow弹出窗体动画效果

this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);

this.listView = (MyListView) conentView.findViewById(R.id.lv_list);

this.arrow_up = (ImageView) conentView.findViewById(R.id.arrow_up);

this.arrow_down = (ImageView) conentView.findViewById(R.id.arrow_down);

//设置适配器

this.selectAdapter = new TypeSelectPopuAdapter(context, typeSelectlist,

R.layout.item_operation_popu);

this.listView.setAdapter(selectAdapter);

this.listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView> parent, View view, int position, long id) {

if (isShowing()) {

dismiss();

}

onItemListener.OnItemListener(position, typeSelectlist.get(position));

}

});

this.setOnDismissListener(new OnDismissListener() {

@Override

public void onDismiss() {

if (backgroundView != null) {

backgroundView.setVisibility(View.GONE);

}

}

});

}

//设置数据

public void setDataSource(List typeSelectlist) {

this.typeSelectlist = typeSelectlist;

this.selectAdapter.notifyDataSetChanged();

}

/**

* 没有半透明背景 显示popupWindow

*

* @param

*/

public void showPopupWindow(View v) {

v.getLocationOnScreen(location); //获取控件的位置坐标

//获取自身的长宽高

conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

if (location[1] > MainApplication.SCREEN_H / 2 + 100) { //MainApplication.SCREEN_H 为屏幕的高度,方法可以自己写

this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);

arrow_up.setVisibility(View.GONE);

arrow_down.setVisibility(View.VISIBLE);

this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight());

} else {

this.setAnimationStyle(R.style.operation_popwindow_anim_style_down);

arrow_up.setVisibility(View.VISIBLE);

arrow_down.setVisibility(View.GONE);

this.showAsDropDown(v, 0, 0);

}

}

/**

* 携带半透明背景 显示popupWindow

*

* @param

*/

public void showPopupWindow(View v, View backgroundView) {

this.backgroundView = backgroundView;

v.getLocationOnScreen(location); //获取控件的位置坐标

//获取自身的长宽高

conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

backgroundView.setVisibility(View.VISIBLE);

//对view执行动画

backgroundView.startAnimation(anim_backgroundView);

if (location[1] > MainApplication.SCREEN_H / 2 + 100) { //若是控件的y轴位置大于屏幕高度的一半,向上弹出

this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);

arrow_up.setVisibility(View.GONE);

arrow_down.setVisibility(View.VISIBLE);

this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight()); //显示指定控件的上方

} else {

this.setAnimationStyle(R.style.operation_popwindow_anim_style_down); //反之向下弹出

arrow_up.setVisibility(View.VISIBLE);

arrow_down.setVisibility(View.GONE);

this.showAsDropDown(v, 0, 0); //显示指定控件的下方

}

}

/**

* 显示popupWindow 根据特殊要求高度显示位置

*

* @param

*/

public void showPopupWindow(View v, View backgroundView,int hight) {

this.backgroundView = backgroundView;

v.getLocationOnScreen(location);

//获取自身的长宽高

conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

backgroundView.setVisibility(View.VISIBLE);

//对view执行动画

backgroundView.startAnimation(anim_backgroundView);

if (location[1] > MainApplication.SCREEN_H / 2 + 100) {

this.setAnimationStyle(R.style.operation_popwindow_anim_style_up);

arrow_up.setVisibility(View.GONE);

arrow_down.setVisibility(View.VISIBLE);

this.showAtLocation(v, Gravity.NO_GRAVITY, (location[0]), location[1] - conentView.getMeasuredHeight()-hight);

} else {

this.setAnimationStyle(R.style.operation_popwindow_anim_style_down);

arrow_up.setVisibility(View.VISIBLE);

arrow_down.setVisibility(View.GONE);

this.showAsDropDown(v, 0, 0);

}

}

}

4.代码中的用法

1.

CustomOperationPopWindow customOperationPopWindow = new CustomOperationPopWindow(this, operationTypeSelectlist);

customOperationPopWindow.setOnItemMyListener(new CustomOperationPopWindow.OnItemListener() {

@Override

public void OnItemListener(int position, TypeSelect typeSelect) {

//此处实现列表点击所要进行的操作

}

});

2.

textView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

customOperationPopWindow.showPopupWindow(textView);//可以传个半透明view v_background过去根据业务需要显示隐藏

}

});

5.最终实际效果

5ab436b0f9f9e287347d90408ffb4d59.png

e2a41a85684a143354fec62cf76b0cb6.png

以上代码为几乎主要全部代码,主要是PopupWindow的用法,思路清晰一步一步实现很简单。

以上所述是小编给大家介绍的Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

这篇关于Android开发空间靠右放代码,Android开发仿QQ空间根据位置弹出PopupWindow显示更多操作效果...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/263667

相关文章

Python正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编