項目GitHub地址:https://github.com/leonInShanghai/IMbobo

GridView XML佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".controller.activity.GroupDetailActivity"> <com.hyphenate.easeui.widget.EaseTitleBar
app:titleBarTitle = "群详情"
android:layout_width = "match_parent"
android:layout_height = "wrap_content" /> <GridView
android:id="@+id/gv_groupdetail"
android:numColumns="4"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp">
</GridView> <Button
android:id="@+id/bt_groupdetail_out"
android:background="@android:color/holo_red_light"
android:textColor="@android:color/white"
android:text="退群"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="60dp" /> </LinearLayout> Activity 類:
package com.example.administrator.imbobo.controller.activity;

import android.app.Activity;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.Toast;
import com.example.administrator.imbobo.controller.adapter.GroupDetailAdapte;
import com.example.administrator.imbobo.R;
import com.example.administrator.imbobo.model.Model;
import com.example.administrator.imbobo.model.bean.UserInfo;
import com.example.administrator.imbobo.utils.Constant;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMGroup;
import com.hyphenate.exceptions.HyphenateException; import java.util.ArrayList;
import java.util.List; /**
* Created by Leon on 2018/11/24
* Functions: 群详情页面
*/
public class GroupDetailActivity extends Activity { /**网格视图*/
private GridView gv_groupdetail; /**退群的按钮*/
private Button bt_groupdetail_out; /**群组类(环信easeUI定义的类*/
private EMGroup mGroup; //群成員集合
private List<UserInfo> mUsers; /**GridView 適配器*/
private GroupDetailAdapte groupDetailAdapte; /**處理 增加 和刪除群成員的業務邏輯的接口*/
private GroupDetailAdapte.OnGroupDetailListener mOnGroupDetailListener = new GroupDetailAdapte.
OnGroupDetailListener() {
@Override
public void onAddMembers() {
//添加群成員-開闢子綫程做網絡請求 } @Override
public void onDeleteMember(UserInfo user) {
//刪除群成員-開闢子綫程做網絡請求
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grour_detail); initView(); /**获取传递过来的环信id*/
getData(); initData();
} private void initData(){
//初始化button显示
initButtonDisplay(); //初始化gridview
initGridView(); //從環信服務器獲取所有的群成員
getMembersFromHxServer();
} /**從環信服務器獲取所有的群成員*/
private void getMembersFromHxServer(){
//開闢子綫程做網絡請求
Model.getInstance().getGloabalThreadPool().execute(new Runnable() {
@Override
public void run() {
try {
//從環信服務器獲取所有的群成員信息
EMGroup emGroup = EMClient.getInstance().groupManager().getGroupFromServer(mGroup.getGroupId());
List<String> menbers = emGroup.getMembers(); if (menbers != null && menbers.size() >= 0){ mUsers = new ArrayList<>(); //轉換
for (String menber : menbers){
UserInfo userInfo = new UserInfo(menber);
mUsers.add(userInfo);
}
} //更新頁面-回到主綫程
runOnUiThread(new Runnable() {
@Override
public void run() {
//刷新適配器
groupDetailAdapte.refresh(mUsers);
}
});
} catch (final HyphenateException e) {
e.printStackTrace();
//更新頁面-回到主綫程
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GroupDetailActivity.this,"獲取群信息失敗"+e.toString(),
Toast.LENGTH_SHORT).show();
}
});
}
}
});
} //初始化gridview
private void initGridView(){ /**
* 群主有邀請人入群的權限
* 另外當 群組是公開的時候群成員也有邀請人的權限
*/
boolean isCanModify = EMClient.getInstance().getCurrentUser().equals(mGroup.getOwner()) ||
mGroup.isPublic(); /**
* 第一個參數是上下文
* 第二個參數是標記 是 群主/群員
*/
groupDetailAdapte = new GroupDetailAdapte(this,isCanModify,
mOnGroupDetailListener); //GridView 設置 adapte
gv_groupdetail.setAdapter(groupDetailAdapte);
} //初始化button显示 - 退群/解散群
private void initButtonDisplay(){ //判断当前用户是否为群组
if (EMClient.getInstance().getCurrentUser().equals(mGroup.getOwner())){//群主
bt_groupdetail_out.setText("解散群"); bt_groupdetail_out.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //开辟子线程-去环信服务器解散群
Model.getInstance().getGloabalThreadPool().execute(new Runnable() {
@Override
public void run() {
try {
//去环信服务器解散群
EMClient.getInstance().groupManager().destroyGroup(mGroup.getGroupId()); //发送一个退群的广播
exitGroupBroatCast(); //更新页面
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GroupDetailActivity.this,"解散群成功",
Toast.LENGTH_SHORT).show(); //结束当前页面
finish();
}
}); } catch (final HyphenateException e) {
e.printStackTrace();
//更新页面
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GroupDetailActivity.this,"解散群失败"+e.toString(),
Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
}); }else {//群成员
bt_groupdetail_out.setText("退群"); bt_groupdetail_out.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开辟子线程做服务器请求操作
Model.getInstance().getGloabalThreadPool().execute(new Runnable() {
@Override
public void run() {
try {
//告诉环信服务器群成员要退群
EMClient.getInstance().groupManager().leaveGroup(mGroup.getGroupId()); //发送一个退群的广播
exitGroupBroatCast(); //更新页面
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GroupDetailActivity.this,"退群成功",
Toast.LENGTH_SHORT).show(); //结束当前页面
finish();
}
});
} catch (final HyphenateException e) {
e.printStackTrace();
//更新页面
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GroupDetailActivity.this,"退群失败"+e.toString(),
Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
});
}
} /**发送退群和解散群广播*/
private void exitGroupBroatCast(){
LocalBroadcastManager mLBM = LocalBroadcastManager.getInstance(GroupDetailActivity.this); Intent intent = new Intent(Constant.EXIT_GROUP); intent.putExtra(Constant.GROUP_ID,mGroup.getGroupId()); mLBM.sendBroadcast(intent);
} /**获取传递过来的数据最终得到一个 mGroup*/
private void getData(){
String groupId = getIntent().getStringExtra(Constant.GROUP_ID); if (groupId == null){
return;
}else {
mGroup = EMClient.getInstance().groupManager().getGroup(groupId);
}
} private void initView(){
gv_groupdetail = (GridView)findViewById(R.id.gv_groupdetail);
bt_groupdetail_out = (Button)findViewById(R.id.bt_groupdetail_out);
}
}

適配器:

package com.example.administrator.imbobo.controller.adapter;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; import com.example.administrator.imbobo.R;
import com.example.administrator.imbobo.model.bean.UserInfo; import java.util.ArrayList;
import java.util.List; /**
* Created by Leon on 2018/11/25.
* Functions: GroupDetailActivity 中的 GridView 的適配器
*/
public class GroupDetailAdapte extends BaseAdapter { private Context mContext; /*是否允許添加和刪除群成員*/
private boolean mIsCanModify; /**GridView 的數據源*/
private List<UserInfo> mUsers = new ArrayList<>(); /**刪除模式 true:表示可以刪除 false:表示不可以刪除*/
private boolean mIsDeleteModle; /**自定義接口 實現添加群成員和 刪除群成員的業務邏輯*/
private OnGroupDetailListener mOnGroupDetailListener; public GroupDetailAdapte(Context context,boolean isCanModify,OnGroupDetailListener onGroupDetailListener) {
this.mContext = context;
this.mIsCanModify = isCanModify;
this.mOnGroupDetailListener = onGroupDetailListener;
} //刷新方法-用於刷新和傳參
public void refresh(List<UserInfo> users){
if (users != null && users.size() >= 0){
//1.清空原有的數據
mUsers.clear(); //2.添加加號和減號
initUsers(); //3.添加數據 - index:0 是爲了把加號 減號 都擠到後面
mUsers.addAll(0,users);
} //刷新頁面
notifyDataSetChanged();
} //添加加號和減號
private void initUsers(){
UserInfo add = new UserInfo("add");
UserInfo delete = new UserInfo("delete"); //添加 加號 和 減號讓它們在數組集合的後邊
mUsers.add(delete);
mUsers.add(0,add);
} @Override
public int getCount() {
return mUsers == null ? 0 : mUsers.size();
} @Override
public Object getItem(int position) {
return mUsers.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) { //1.獲取或創建ViewHolder
ViewHolder holder = null; if (convertView == null){
holder = new ViewHolder(); convertView = View.inflate(mContext, R.layout.item_groupdetail,null); holder.photo = (ImageView) convertView.findViewById(R.id.iv_group_detail_photo);
holder.delete = (ImageView)convertView.findViewById(R.id.iv_group_detatil_delete);
holder.name = (TextView)convertView.findViewById(R.id.tv_group_detail_name); convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
} //2.獲取當前item數據
final UserInfo userInfo = mUsers.get(position); //3.顯示數據
if (mIsCanModify){//群主 或 公開群權限裏的群成員
//佈局的處理
if (position == getCount() - 1){//減號的位置特殊處理
//刪除模式判斷
if (mIsDeleteModle){
convertView.setVisibility(View.GONE);
}else {
convertView.setVisibility(View.VISIBLE); holder.photo.setImageResource(R.drawable.em_smiley_minus_btn);
holder.delete.setVisibility(View.GONE);
holder.name.setVisibility(View.INVISIBLE);
}
}else if (position == getCount() -2){//加號的位置特殊處理
//刪除模式判斷(增刪模式)
if (mIsDeleteModle){
convertView.setVisibility(View.GONE);
}else {
convertView.setVisibility(View.VISIBLE); holder.photo.setImageResource(R.drawable.em_smiley_add_btn);
holder.delete.setVisibility(View.GONE);
holder.name.setVisibility(View.INVISIBLE);
}
}else {//群成員
convertView.setVisibility(View.VISIBLE);
holder.name.setVisibility(View.VISIBLE); //名稱 由於我這裏昵稱是手機號太長,所以只顯示后四位
if (userInfo.getName() != null){
String name = userInfo.getName().substring(userInfo.getName().length()-4,userInfo.getName().length());
holder.name.setText(name);
}
holder.photo.setImageResource(R.drawable.em_default_avatar); if (mIsDeleteModle){//刪除(增刪)模式
holder.delete.setVisibility(View.VISIBLE);
}else {//非 刪除(增刪)模式
holder.delete.setVisibility(View.GONE);
}
} //點擊事件的處理
if (position == getCount() - 1){//減號的位置
holder.photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mIsDeleteModle){
mIsDeleteModle = true;
notifyDataSetChanged();
}
}
});
}else if (position == getCount() - 2){//加號的位置
holder.photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnGroupDetailListener.onAddMembers();
}
}); }else {//群成員的位置 delete 點擊事件的處理
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnGroupDetailListener.onDeleteMember(userInfo);
}
});
}
}else{//普通的群成員
if (position == getCount() - 1 || position == getCount() - 2){//減號和加號的位置隱藏掉
convertView.setVisibility(View.GONE);
}else{
convertView.setVisibility(View.VISIBLE); //名稱 由於我這裏昵稱是手機號太長,所以只顯示后四位
if (userInfo.getName() != null){
String name = userInfo.getName().substring(userInfo.getName().length()-4,userInfo.getName().length());
holder.name.setText(name);
} //頭像
holder.photo.setImageResource(R.drawable.em_default_avatar); //刪除按鈕 - 普通成員沒有權力刪除和邀請群成員
holder.delete.setVisibility(View.GONE);
}
} //4.返回View
return convertView;
} /**内部類 ViewHolder*/
private class ViewHolder{
private ImageView photo;
private ImageView delete;
private TextView name;
} /**自定義接口 誰實現誰處理 刪除群成員 和添加群成員的業務邏輯*/
public interface OnGroupDetailListener{
/**添加群成員方法*/
void onAddMembers(); /**刪除群成員方法*/
void onDeleteMember(UserInfo user);
}
}

GridView的簡單使用的更多相关文章

  1. [SharePoint 2010] Visual Studio 2010內撰寫視覺化WebPart超簡單

    新一代的Visual Studio 2010對於SharePoint 2010的專案撰寫,有非常另人讚賞的改進. 以往寫一個WebPart要搞好多雜七雜八的步驟,也要硬寫HTML輸出,當然有人說可以寫 ...

  2. 簡單工廠模式-之-什麼是產品線 And 抽象工廠模式-之-什麼是產品族

    簡單工廠模式-之-什麼是產品線 簡單工廠模式中,有一個概念就是使用了多層次的產品結構,那麼什麼是產品結構或者說什麼是產品線? 假定我們有一個基準的產品標準Product,那麼所有繼承該基類或者傳遞基類 ...

  3. [Xamarin] 簡單使用Fragment 靜態篇 (转帖)

    新的Android 開發,非常會使用到Fragment,不過官方範例有點小複雜,對初學者來說有點難消化,所以就記錄一下心得,這邊部落格將使用靜態的方法使用Fragment,Fragment 有自己的生 ...

  4. [Xamarin] 簡單使用AlertDialog (转帖)

    這東西跟Toast 很像,有方便提示的作用 像是Windows 上面的MessageBox 或是 Javascript 的 Alert 會先阻斷使用者並且下一個決定 很簡單我就不贅述,基本上透過 Al ...

  5. 簡單SQL存儲過程實例

    簡單SQL存儲過程實例 摘自:http://blog.csdn.net/libra6956/article/details/5589173 实例1:只返回单一记录集的存储过程. 银行存款表(bankM ...

  6. 转:[ASP.NET]重構之路系列v4 – 簡單使用interface之『你也會IoC』

    前言 上次v3版本,我們將Entity, Service, Dao, Utility都放到了類別庫裡面,讓我們可以輕鬆的在不同專案中用同一份組件.雖然文章沒有獲得太多的讚賞,不過相信那一定是太多人會這 ...

  7. COB(Chip On Board)的製程簡單介紹

    前面提及 COB 的生產與 IC 的封裝製程幾乎是一致的,除了把 leadframe 改成了 PCB,把封膠由 molding 改成 dispensing,少了 triming & marki ...

  8. 【转】簡單講講 USB Human Interface Device

    原地址http://213style.blogspot.com/2013/09/usb-human-interface-device.html 恩,發本文的原因是看到了以前畢業的朋友在旁邊的對話框問了 ...

  9. HTML Agility Pack:簡單好用的快速 HTML Parser

    HTML Agility Pack:簡單好用的快速 HTML Parser Codeplex 軟體套件(Package)資訊 套件名稱 HTML Agility Pack 作者 Simon Mouri ...

随机推荐

  1. vue脚手架构

    我们是用Eclipse开发的,所以用vue开始时,要进行代理,不然访问不到服务器,所以就需要配置一下 dev  context 里面写的是代理的接口,就是以这些接口开头的,如果没有就往里写一下,pro ...

  2. Docker学习之4——构建NGINX镜像

    Nginx是一个高性能的Web和反向代理服务器,它具有很多非常优越的特性:1.作为Web服务器.2.作为负载均衡服务器.3.作为邮件代理服务器.4.安装及配置简单.接下来我们介绍在docker构建ng ...

  3. 在Hadoop集群上的HBase配置

    之前,我们已经在hadoop集群上配置了Hive,今天我们来配置下Hbase. 一.准备工作 1.ZooKeeper下载地址:http://archive.apache.org/dist/zookee ...

  4. 深入C#并行编程(1) -- 了解线程

    一.操作系统用进程(Processe)分隔正在执行的程序,用线程(Thread)作为操作系统分配处理器时间的基本单元,进程上下文中可以运行多个线程,进程的所有线程共享其虚拟地址空间,所有线程均可执行程 ...

  5. 关于QT中.pro文件中的相对路径

    被.pro文件中的相对路径给整糊涂了,仔细研究后,原来.pro文件中有两种相对路径. 一种情况下./表示.pro文件所在的目录 另一种情况下./表示构建生成目录 INCLUDEPATH SOURCE ...

  6. PHP 5.3中的命名空间使用方法

    PHP的命名空间(namespace)是php5.3之后才有的.这个概念在C#中已经很早就有了,php中的namespace其实和c#的概念是一样的. 为什么php中要使用namespace? 假设如 ...

  7. 多模块拆分时 DepencyManagement 与 Dependencys区别

    1.DepencyManagement dependencyManagement让子项目中引用一个依赖而不用显示的列出版本号.Maven会沿着父子层次向上走,直到找到一个拥有dependencyMan ...

  8. JavaWeb学习 (十五)————JSP指令

    一.JSP指令简介 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: pa ...

  9. #14 Python模块

    前言 前面的文章中,有许多地方都用到了Python的模块,这个到底是个什么神奇的东西呢?让我们来一起盘它! 一.什么是模块 在前几节中,我们已经接触了一些模块:math.random.time等,它们 ...

  10. Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate';

    springboot jdbc查询使用LocalDate报:Failed to convert value of type 'java.lang.String' to required type 'j ...