本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下

楼主是在平板上測试的。图片略微有点大,大家看看效果就好

接下来贴源代码:

PinnedHeaderExpandableListView.java

要注意的是 在 onGroupClick方法中parent.setSelectedGroup(groupPosition)这句代码的作用是点击分组置顶,

我这边不须要这个效果。QQ也没实用到,所以给凝视了。大家假设须要能够解开凝视

package com.xiaos.view;

import android.content.Context;

import android.graphics.Canvas;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AbsListView;

import android.widget.AbsListView.OnScrollListener;

import android.widget.ExpandableListAdapter;

import android.widget.ExpandableListView;

import android.widget.ExpandableListView.OnGroupClickListener;

public class PinnedHeaderExpandableListView extends ExpandableListView implements OnScrollListener,OnGroupClickListener {

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

super(context, attrs, defStyle);

registerListener();

}

public PinnedHeaderExpandableListView(Context context, AttributeSet attrs) {

super(context, attrs);

registerListener();

}

public PinnedHeaderExpandableListView(Context context) {

super(context);

registerListener();

}

/**

* Adapter 接口 . 列表必须实现此接口 .

*/

public interface HeaderAdapter {

public static final int PINNED_HEADER_GONE = 0;

public static final int PINNED_HEADER_VISIBLE = 1;

public static final int PINNED_HEADER_PUSHED_UP = 2;

/**

* 获取 Header 的状态

* @param groupPosition

* @param childPosition

* @return PINNED_HEADER_GONE,PINNED_HEADER_VISIBLE,PINNED_HEADER_PUSHED_UP 当中之中的一个

*/

int getHeaderState(int groupPosition, int childPosition);

/**

* 配置 Header, 让 Header 知道显示的内容

* @param header

* @param groupPosition

* @param childPosition

* @param alpha

*/

void configureHeader(View header, int groupPosition,int childPosition, int alpha);

/**

* 设置组按下的状态

* @param groupPosition

* @param status

*/

void setGroupClickStatus(int groupPosition, int status);

/**

* 获取组按下的状态

* @param groupPosition

* @return

*/

int getGroupClickStatus(int groupPosition);

}

private static final int MAX_ALPHA = 255;

private HeaderAdapter mAdapter;

/**

* 用于在列表头显示的 View,mHeaderViewVisible 为 true 才可见

*/

private View mHeaderView;

/**

* 列表头是否可见

*/

private boolean mHeaderViewVisible;

private int mHeaderViewWidth;

private int mHeaderViewHeight;

public void setHeaderView(View view) {

mHeaderView = view;

AbsListView.LayoutParams lp = new AbsListView.LayoutParams(

ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

view.setLayoutParams(lp);

if (mHeaderView != null) {

setFadingEdgeLength(0);

}

requestLayout();

}

private void registerListener() {

setOnScrollListener(this);

setOnGroupClickListener(this);

}

/**

* 点击 HeaderView 触发的事件

*/

private void headerViewClick() {

long packedPosition = getExpandableListPosition(this.getFirstVisiblePosition());

int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition);

if (mAdapter.getGroupClickStatus(groupPosition) == 1) {

this.collapseGroup(groupPosition);

mAdapter.setGroupClickStatus(groupPosition, 0);

}

else{

this.expandGroup(groupPosition);

mAdapter.setGroupClickStatus(groupPosition, 1);

}

this.setSelectedGroup(groupPosition);

}

private float mDownX;

private float mDownY;

/**

* 假设 HeaderView 是可见的 , 此函数用于推断是否点击了 HeaderView, 并对做对应的处理 ,

* 由于 HeaderView 是画上去的 , 所以设置事件监听是无效的 , 仅仅有自行控制 .

*/

@Override

public boolean onTouchEvent(MotionEvent ev) {

if (mHeaderViewVisible) {

switch (ev.getAction()) {

case MotionEvent.ACTION_DOWN:

mDownX = ev.getX();

mDownY = ev.getY();

if (mDownX <= mHeaderViewWidth && mDownY <= mHeaderViewHeight) {

return true;

}

break;

case MotionEvent.ACTION_UP:

float x = ev.getX();

float y = ev.getY();

float offsetX = Math.abs(x - mDownX);

float offsetY = Math.abs(y - mDownY);

// 假设 HeaderView 是可见的 , 点击在 HeaderView 内 , 那么触发 headerClick()

if (x <= mHeaderViewWidth && y <= mHeaderViewHeight

&& offsetX <= mHeaderViewWidth && offsetY <= mHeaderViewHeight) {

if (mHeaderView != null) {

headerViewClick();

}

return true;

}

break;

default:

break;

}

}

return super.onTouchEvent(ev);

}

@Override

public void setAdapter(ExpandableListAdapter adapter) {

super.setAdapter(adapter);

mAdapter = (HeaderAdapter) adapter;

}

/**

*

* 点击了 Group 触发的事件 , 要依据依据当前点击 Group 的状态来

*/

@Override

public boolean onGroupClick(ExpandableListView parent,View v,int groupPosition,long id) {

if (mAdapter.getGroupClickStatus(groupPosition) == 0) {

mAdapter.setGroupClickStatus(groupPosition, 1);

parent.expandGroup(groupPosition);

//Header自己主动置顶

//parent.setSelectedGroup(groupPosition);

} else if (mAdapter.getGroupClickStatus(groupPosition) == 1) {

mAdapter.setGroupClickStatus(groupPosition, 0);

parent.collapseGroup(groupPosition);

}

// 返回 true 才干够弹回第一行 , 不知道为什么

return true;

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

if (mHeaderView != null) {

measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);

mHeaderViewWidth = mHeaderView.getMeasuredWidth();

mHeaderViewHeight = mHeaderView.getMeasuredHeight();

}

}

private int mOldState = -1;

@Override

protected void onLayout(boolean changed, int left, int top, int right,int bottom) {

super.onLayout(changed, left, top, right, bottom);

final long flatPostion = getExpandableListPosition(getFirstVisiblePosition());

final int groupPos = ExpandableListView.getPackedPositionGroup(flatPostion);

final int childPos = ExpandableListView.getPackedPositionChild(flatPostion);

int state = mAdapter.getHeaderState(groupPos, childPos);

if (mHeaderView != null && mAdapter != null && state != mOldState) {

mOldState = state;

mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);

}

configureHeaderView(groupPos, childPos);

}

public void configureHeaderView(int groupPosition, int childPosition) {

if (mHeaderView == null || mAdapter == null

|| ((ExpandableListAdapter) mAdapter).getGroupCount() == 0) {

return;

}

int state = mAdapter.getHeaderState(groupPosition, childPosition);

switch (state) {

case HeaderAdapter.PINNED_HEADER_GONE: {

mHeaderViewVisible = false;

break;

}

case HeaderAdapter.PINNED_HEADER_VISIBLE: {

mAdapter.configureHeader(mHeaderView, groupPosition,childPosition, MAX_ALPHA);

if (mHeaderView.getTop() != 0){

mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);

}

mHeaderViewVisible = true;

break;

}

case HeaderAdapter.PINNED_HEADER_PUSHED_UP: {

View firstView = getChildAt(0);

int bottom = firstView.getBottom();

// intitemHeight = firstView.getHeight();

int headerHeight = mHeaderView.getHeight();

int y;

int alpha;

if (bottom < headerHeight) {

y = (bottom - headerHeight);

alpha = MAX_ALPHA * (headerHeight + y) / headerHeight;

} else {

y = 0;

alpha = MAX_ALPHA;

}

mAdapter.configureHeader(mHeaderView, groupPosition,childPosition, alpha);

if (mHeaderView.getTop() != y) {

mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);

}

mHeaderViewVisible = true;

break;

}

}

}

@Override

/**

* 列表界面更新时调用该方法(如滚动时)

*/

protected void dispatchDraw(Canvas canvas) {

super.dispatchDraw(canvas);

if (mHeaderViewVisible) {

//分组栏是直接绘制到界面中。而不是增加到ViewGroup中

drawChild(canvas, mHeaderView, getDrawingTime());

}

}

@Override

public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {

final long flatPos = getExpandableListPosition(firstVisibleItem);

int groupPosition = ExpandableListView.getPackedPositionGroup(flatPos);

int childPosition = ExpandableListView.getPackedPositionChild(flatPos);

configureHeaderView(groupPosition, childPosition);

}

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

}

}

PinnedHeaderExpandableAdapter.java 适配器

实现了PinnedHeaderExpandableListView中HeaderAdapter接口

package com.xiaos.adapter;

import android.content.Context;

import android.util.SparseIntArray;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseExpandableListAdapter;

import android.widget.ImageView;

import android.widget.TextView;

import com.xiaos.pinnedheaderexpandable.R;

import com.xiaos.view.PinnedHeaderExpandableListView;

import com.xiaos.view.PinnedHeaderExpandableListView.HeaderAdapter;

public class PinnedHeaderExpandableAdapter extends BaseExpandableListAdapter implements HeaderAdapter{

private String[][] childrenData;

private String[] groupData;

private Context context;

private PinnedHeaderExpandableListView listView;

private LayoutInflater inflater;

public PinnedHeaderExpandableAdapter(String[][] childrenData,String[] groupData

,Context context,PinnedHeaderExpandableListView listView){

this.groupData = groupData;

this.childrenData = childrenData;

this.context = context;

this.listView = listView;

inflater = LayoutInflater.from(this.context);

}

@Override

public Object getChild(int groupPosition, int childPosition) {

return childrenData[groupPosition][childPosition];

}

@Override

public long getChildId(int groupPosition, int childPosition) {

return 0;

}

@Override

public View getChildView(int groupPosition, int childPosition,

boolean isLastChild, View convertView, ViewGroup parent) {

View view = null;

if (convertView != null) {

view = convertView;

} else {

view = createChildrenView();

}

TextView text = (TextView)view.findViewById(R.id.childto);

text.setText(childrenData[groupPosition][childPosition]);

return view;

}

@Override

public int getChildrenCount(int groupPosition) {

return childrenData[groupPosition].length;

}

@Override

public Object getGroup(int groupPosition) {

return groupData[groupPosition];

}

@Override

public int getGroupCount() {

return groupData.length;

}

@Override

public long getGroupId(int groupPosition) {

return 0;

}

@Override

public View getGroupView(int groupPosition, boolean isExpanded,

View convertView, ViewGroup parent) {

View view = null;

if (convertView != null) {

view = convertView;

} else {

view = createGroupView();

}

ImageView iv = (ImageView)view.findViewById(R.id.groupIcon);

if (isExpanded) {

iv.setImageResource(R.drawable.btn_browser2);

}

else{

iv.setImageResource(R.drawable.btn_browser);

}

TextView text = (TextView)view.findViewById(R.id.groupto);

text.setText(groupData[groupPosition]);

return view;

}

@Override

public boolean hasStableIds() {

return true;

}

@Override

public boolean isChildSelectable(int groupPosition, int childPosition) {

return true;

}

private View createChildrenView() {

return inflater.inflate(R.layout.child, null);

}

private View createGroupView() {

return inflater.inflate(R.layout.group, null);

}

@Override

public int getHeaderState(int groupPosition, int childPosition) {

final int childCount = getChildrenCount(groupPosition);

if (childPosition == childCount - 1) {

return PINNED_HEADER_PUSHED_UP;

} else if (childPosition == -1

&& !listView.isGroupExpanded(groupPosition)) {

return PINNED_HEADER_GONE;

} else {

return PINNED_HEADER_VISIBLE;

}

}

@Override

public void configureHeader(View header, int groupPosition,

int childPosition, int alpha) {

String groupData = this.groupData[groupPosition];

((TextView) header.findViewById(R.id.groupto)).setText(groupData);

}

private SparseIntArray groupStatusMap = new SparseIntArray();

@Override

public void setGroupClickStatus(int groupPosition, int status) {

groupStatusMap.put(groupPosition, status);

}

@Override

public int getGroupClickStatus(int groupPosition) {

if (groupStatusMap.keyAt(groupPosition)>=0) {

return groupStatusMap.get(groupPosition);

} else {

return 0;

}

}

}

MainActivity.java主Activity

package com.xiaos.pinnedheaderexpandable;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.ExpandableListView;

import android.widget.ExpandableListView.OnGroupClickListener;

import com.xiaos.adapter.PinnedHeaderExpandableAdapter;

import com.xiaos.view.PinnedHeaderExpandableListView;

public class MainActivity extends Activity{

private PinnedHeaderExpandableListView explistview;

private String[][] childrenData = new String[10][10];

private String[] groupData = new String[10];

private int expandFlag = -1;//控制列表的展开

private PinnedHeaderExpandableAdapter adapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.layout_main);

initView();

initData();

}

/**

* 初始化VIEW

*/

private void initView() {

explistview = (PinnedHeaderExpandableListView)findViewById(R.id.explistview);

}

/**

* 初始化数据

*/

private void initData() {

for(int i=0;i<10;i++){

groupData[i] = "分组"+i;

}

for(int i=0;i<10;i++){

for(int j=0;j<10;j++){

childrenData[i][j] = "好友"+i+"-"+j;

}

}

//设置悬浮头部VIEW

explistview.setHeaderView(getLayoutInflater().inflate(R.layout.group_head,

explistview, false));

adapter = new PinnedHeaderExpandableAdapter(childrenData, groupData, getApplicationContext(),explistview);

explistview.setAdapter(adapter);

//设置单个分组展开

//explistview.setOnGroupClickListener(new GroupClickListener());

}

class GroupClickListener implements OnGroupClickListener{

@Override

public boolean onGroupClick(ExpandableListView parent, View v,

int groupPosition, long id) {

if (expandFlag == -1) {

// 展开被选的group

explistview.expandGroup(groupPosition);

// 设置被选中的group置于顶端

explistview.setSelectedGroup(groupPosition);

expandFlag = groupPosition;

} else if (expandFlag == groupPosition) {

explistview.collapseGroup(expandFlag);

expandFlag = -1;

} else {

explistview.collapseGroup(expandFlag);

// 展开被选的group

explistview.expandGroup(groupPosition);

// 设置被选中的group置于顶端

explistview.setSelectedGroup(groupPosition);

expandFlag = groupPosition;

}

return true;

}

}

}

布局文件

child.xml

android:layout_width="match_parent"

android:layout_height="40dip"

android:background="#FFFFFF" >

android:id="@+id/groupIcon"

android:layout_width="40dp"

android:layout_height="40dp"

android:paddingLeft="10dp"

android:src="@null" />

android:id="@+id/childto"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingLeft="10dp"

android:paddingTop="10dip"

android:textColor="#000000"

android:textSize="16sp" />

group_head.xml

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:background="#B8E6FA"

android:gravity="center_vertical">

android:id="@+id/groupIcon"

android:layout_width="50dp"

android:layout_height="50dp"

android:contentDescription="@null"

android:layout_marginLeft="10dp"

android:src="@drawable/btn_browser2"/>

android:id="@+id/groupto"

android:layout_width="match_parent"

android:layout_height="50dp"

android:textColor="#000000"

android:textSize="18sp"

android:gravity="center_vertical|left"/>

group.xml

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:background="#B8E6FA"

android:gravity="center_vertical">

android:id="@+id/groupIcon"

android:layout_width="50dp"

android:layout_height="50dp"

android:contentDescription="@null"

android:layout_marginLeft="10dp"

android:src="@drawable/btn_browser"/>

android:id="@+id/groupto"

android:layout_width="match_parent"

android:layout_height="50dp"

android:textColor="#000000"

android:textSize="18sp"

android:gravity="center_vertical|left"/>

layout_main.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#F0F0F0"

android:orientation="vertical" >

android:id="@+id/explistview"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_marginLeft="0.0dip"

android:cacheColorHint="#00000000"

android:choiceMode="singleChoice"

android:drawSelectorOnTop="false"

android:fastScrollEnabled="false"

android:footerDividersEnabled="true"

android:groupIndicator="@null"

android:scrollbars="vertical"

android:scrollingCache="true" />

AndroidManifest.xml

package="com.xiaos.pinnedheaderexpandable"

android:versionCode="1"

android:versionName="1.0" >

android:minSdkVersion="8"

android:targetSdkVersion="19" />

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

android:name=".MainActivity"

android:icon="@drawable/ic_launcher">

两张图片:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android 仿qq好友动态,Android UI仿QQ好友列表分组悬浮效果相关推荐

  1. 仿QQ好友列表分组折叠效果

    最近要一个类似QQ好友列表分组折叠效果,经过网友提醒应该使用ExpandableListView,因为其就集成了这个功能,我到网上随便找了文章一看,果然如此,因为工作需要和兴趣的推动,下班做完事后决定 ...

  2. Android UI视图效果篇之仿QQ好友列表分组悬浮PinnedHeaderExpandableListView

    楼主是在平板上测试的,图片稍微有点大,大家看看效果就好 接下来贴源码: PinnedHeaderExpandableListView.java 要注意的是 在 onGroupClick方法中paren ...

  3. android仿微博发动态,Android GridView扩展仿微信微博发图动态添加删除图片功能

    在平时的开发中,我们会看到不管是微信发朋友圈照片还是微博发布新鲜事,添加图片的时候都是选完后面还有个+号再去选择图片,这样的话比较方便用户去添加图片,有的右上角还有个-号方便用户去删除图片,而一般用户 ...

  4. android 仿qq发动态,Android opengl 实现动态贴纸(仿QQ的拍摄)

    回顾 在前面视频录制篇尾(https://www.jianshu.com/p/4f63b2436401)中有提到视频录制+人脸识别+贴纸的想法,而上一篇(https://www.jianshu.com ...

  5. android写qq动态界面,Android_Android仿QQ空间主页面的实现,今天模仿安卓QQ空间,效果如 - phpStudy...

    Android仿QQ空间主页面的实现 今天模仿安卓QQ空间,效果如下: 打开程序的启动画面和导航页面我就不做了,大家可以模仿微信的那个做一下,很简单.这次主要做一下主页面的实现,下面是主页面的布局: ...

  6. android仿qq动态,Android仿QQ空间主页面的实现

    今天模仿安卓QQ空间,效果如下: 打开程序的启动画面和导航页面我就不做了,大家可以模仿微信的那个做一下,很简单.这次主要做一下主页面的实现,下面是主页面的布局: android:layout_widt ...

  7. dynamic 365 js 失去焦点_基于Auto.js的QQ好友动态秒赞系统

    0.脑筋急转弯 请问在什么情况下 log(10) == 10 log(20) == 20 左滑查看答案                                                c ...

  8. android平板专区,平板电脑QQ空间HD( Android Pad )1.0

    [IT168厂商动态]日前 , 腾讯为Android平板用户精心打造的QQ空间HD( Android Pad )1.0正式发布. 首个 QQ空间HD( Android Pad ) 版本 界面 清新,交 ...

  9. QQ显示服务器繁忙2013,在QQ空间发表日志的之后为什么样总是显示“服务器繁忙”?...

    据小米方面介绍,小米手机认证空间帐号自2013年5月21日开通以来,框架,8mm加厚钢化玻璃,15mm防火板材质机壳3. 在QQ空间发表日志的之后为什么总是显示"服务器繁忙",发表 ...

最新文章

  1. 文件特殊权限suid、sgid、stick_bit、硬链接、软链接
  2. swiper 定义放多少张图片_swiper轮播问题之二:默认显示3张图片,中间显示全部两边显示部分...
  3. xend: No such file or directory. Is xend running? 问题
  4. Distance计算的距离随经纬度不同
  5. 【读一本书】《昇腾AI处理器架构与编程》--神经网络基础知识(2)
  6. mysql存储ip地址_MySQL怎样存储IP地址
  7. Java 8 时间日期库的20个使用演示样例
  8. LM NTLM ophcrack RainBow table (转)
  9. (八)java版spring cloud+spring boot+redis多租户社交电子商务平台 -SSO单点登录之OAuth2.0登录认证(2)...
  10. 如何保证数据库结构的合理性(三、建立可靠的关系)
  11. 文件转换base64流
  12. Adobe Reader 8 简体中文版最新版本
  13. 【算法篇】汉诺塔问题
  14. 详解数据库锁机制和原理
  15. 【FPGA】按键消抖
  16. shell脚本 插队
  17. php清除垃圾代码,批处理清理系统垃圾代码,简单快速实用(适用于xp win7)
  18. 天大18年c语言离线作业,2018春 Python语言程序设计(天津大学仁爱学院)-中国大学mooc-题库零氪...
  19. Java前叉夹器_大器晚成 SRAM S-900直装夹器评测
  20. 简单介绍线上点餐APP开发用途

热门文章

  1. 光学识别OCR软件Readiris Pro 17 for Mac
  2. AcWing 4411. 三仙归洞 (简单模拟)
  3. 小米10s微距模式使用教程分享
  4. 浅谈信息化,数字化,元宇宙,未来IT行业的机遇
  5. 不可重复读和幻读的区别
  6. Android内存泄露抓取工具leakcanary
  7. 一文弄懂Python中的Lambda表达式
  8. 一些关于国内腿足式机器人公司研究所的信息分享
  9. 【UCIe】UCIe 协议层介绍
  10. JS 控制文本框只能输入中文、英文、数字与指定特殊符号(屏蔽表情输入)