Flutter高仿微信系列共59篇,从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。
详情请查看
效果图:

实现代码:
/**
* Author : wangning
* Email : maoning20080809@163.com
* Date : 2022/8/17 15:48
* Description : 新的朋友
*/
class NewFriends extends StatelessWidget {
const NewFriends({super.key});
@override
Widget build(BuildContext context) {
return const NewFriendsPage(title: '新的朋友');
}
}
class NewFriendsPage extends StatefulWidget {
const NewFriendsPage({super.key, required this.title});
final String title;
@override
State<NewFriendsPage> createState() => _NewFriendsPageState();
}
class _NewFriendsPageState extends State<NewFriendsPage> {
final ScrollController _scrollController = ScrollController(); //listview 的控制器
List<ContactsBeanComb> _contactList = [];
var json; //是否正在加载数据
@override
void initState() {
super.initState();
_updateStatus();
_getData();
//下面这个方法每次都底部都会执行,上面的代码只会执行一次
_scrollController.addListener(() {
if (_scrollController.position.pixels >
_scrollController.position.maxScrollExtent - 20) {
_getData();
}
});
}
//更改状态
void _updateStatus() async {
ContactsRepository.getInstance().updateContactStatusRead();
Map<String, Object> result = HashMap<String, Object>();
eventBus.emit(BaseEvent(BaseEvent.TYPE_READ_FRIENDS, result: result));
}
//加载数据
_getData() async {
List<ContactsBeanComb> contactList = await ContactsRepository.getInstance().findAllContactsCombNew();
_contactList = [];
setState(() {
_contactList = contactList;
});
}
//没有好友请求显示
Widget _noDataWidget() {
return Center(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('没有新的朋友...',style: TextStyle(fontSize: 16.0),)
],
),
),
);
}
Future<void> _onRefresh() async {
await Future.delayed(Duration(seconds: 3), () {
LogUtils.d('通讯录refresh');
});
}
//接受好友邀请
void _receiveFriends(ContactsBeanComb contactsBeanComb){
XmppManager.getInstance().createRoster(contactsBeanComb.toAccount);
ContactsBean contactsBean = ContactsBean();
contactsBean.id = contactsBeanComb.id;
contactsBean.fromAccount = contactsBeanComb.fromAccount;
contactsBean.toAccount = contactsBeanComb.toAccount;
contactsBean.type = ContactsBean.typeReceive;
contactsBean.addTime = contactsBeanComb.addTime;
ContactsRepository.getInstance().updateContactLocal(contactsBean);
ContactsRepository.getInstance().updateContactServer(contactsBean);
ChatSendBean chatSendBean = ChatSendBean();
chatSendBean.contentType = CommonUtils.TYPE_RECEIVE_FRIENDS;
chatSendBean.content = contactsBeanComb.toAccount;
String message = jsonEncode(chatSendBean);
_sendMessage(contactsBeanComb.fromAccount, message);
Map<String, Object> result = HashMap<String, Object>();
eventBus.emit(BaseEvent(BaseEvent.TYPE_RECEIVE_FRIENDS, result: result));
Navigator.pop(context);
}
//发送消息
_sendMessage(String toAccount, var message){
int id = DateTime.now().millisecondsSinceEpoch;
String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT);
String toJid = toAccount + "@wangning";
XmppManager.getInstance().sendMessage(toJid, message, "$account", id);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: WnAppBar.getAppBar(context, Text("${widget.title}")),
body: Column(
children: [
Expanded(
child:_contactList.length > 0
? RefreshIndicator(
onRefresh: _onRefresh,
child: ListView.builder(
itemCount: _contactList.length,
controller: _scrollController,
itemBuilder: (context, index) {
return InkWell(
onLongPress: (){
_showDeleteDialog(_contactList[index].fromAccount, _contactList[index].toAccount);
},
onTap: (){
},
child: Container(
decoration: BoxDecoration(border: Border(bottom:BorderSide(color: Color(0xffd9d9d9), width: 0.3))),
width: double.infinity,
padding: EdgeInsets.only(left: 14, top: 10, bottom: 10),
child: Row(
children: [
CommonAvatarView.showBaseImage(_contactList[index].avatar),
SizedBox(width: 12,),
Text(_contactList[index].nickName, maxLines: 1,style: TextStyle(fontSize: 18, color: Colors.black, fontWeight: FontWeight.bold),),
SizedBox(width: 12,),
Expanded(child: SizedBox()),//自动扩展挤压
_getFriendsStatus(_contactList[index]),
],
),
),
);
}))
: _noDataWidget()
),
],
),
);
}
//删除对话框
Future<void> _showDeleteDialog(String fromAccount, String toAccount) async {
return showDialog<Null>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('确定要删除该好友吗?', style: new TextStyle(fontSize: 17.0)),
actions: <Widget>[
MaterialButton(
child: Text('取消'),
onPressed: (){
LogUtils.d("确定取消");
Navigator.of(context).pop();
},
),
MaterialButton(
child: Text('确定'),
onPressed: (){
LogUtils.d("确定删除");
Navigator.pop(context);
_deleteContacts(fromAccount, toAccount);
},
)
],
);
}
);
}
//删除联系人
_deleteContacts(String fromAccount, String toAccount) async{
bool deleteServerFlag = await ContactsRepository.getInstance().deleteContactsByAccountServer(fromAccount, toAccount);
if(deleteServerFlag){
bool deleteFlag = await ContactsRepository.getInstance().deleteContactsByAccount(fromAccount, toAccount);
if(deleteFlag){
CommonToast.show(context, "删除成功!");
_getData();
} else {
CommonToast.show(context, "删除失败!");
}
} else {
CommonToast.show(context, "删除失败!");
}
}
Widget _getFriendsStatus(ContactsBeanComb contactsBeanComb){
String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT);
LogUtils.d("新的朋友 _getFriendsStatus ${account} , ${contactsBeanComb.fromAccount}, ${contactsBeanComb.toAccount}");
if(contactsBeanComb.fromAccount == account) {
LogUtils.d("已发送");
return GestureDetector(
onLongPress: (){
_receiveFriends(contactsBeanComb);
},
child: Container(
margin: EdgeInsets.only(left: 12.0, right: 12),
child: Text("已发送"),
),
);
} else if(contactsBeanComb.type == ContactsBean.typeRequest||contactsBeanComb.type == ContactsBean.typeRead){
LogUtils.d("同意按钮");
return Container(
margin: EdgeInsets.only(left: 12.0, right: 12),
child: MaterialButton(
color: Colors.green,
textColor: Colors.white,
child: Text("同意"),
onPressed: (){
LogUtils.d("新的朋友点击添加");
_receiveFriends(contactsBeanComb);
},
),
);
}
return Text("");
}
}



















