Die Tastaturanzeige erzeugt in der Flutter-App auf Android seltsame SprüngeAndroid

Forum für diejenigen, die für Android programmieren
Guest
 Die Tastaturanzeige erzeugt in der Flutter-App auf Android seltsame Sprünge

Post by Guest »

Auf einem Chat-Bildschirm, wenn man sich auf die Nachrichteneingabe am unteren Bildschirmrand konzentriert, verhält sich das Layout seltsam, am Ende der Animation ist ein leichter Sprung sichtbar.
Das passierte nur auf meinem Android Pixel 7 Auf dem physischen Gerät gab es dieses Problem vor ein paar Monaten noch nicht. Möglicherweise liegt es an einem neuen Android-Update.
Es gibt kein Problem mit dem Android-Emulator Pixel 7a und iOS.
Video des Fehlers :
https://streamable.com/kr66l3
Hier ist der Code:

Code: Select all

import 'package:flutter/material.dart';

class Chat {
final String message;
final bool isSender;

Chat({required this.message, required this.isSender});
}

class ChatScreen extends StatefulWidget {
const ChatScreen({super.key});

@override
State createState() => ChatScreenState();
}

class ChatScreenState extends State {
final List _chatList = [
Chat(message: 'こんにちは!', isSender: false),
Chat(message: 'こんにちは!お元気ですか?', isSender: true),
Chat(message: 'はい、元気です。あなたは?', isSender: false),
Chat(message: '私も元気です。最近どうですか?', isSender: true),
Chat(message: '忙しいですが、充実しています。', isSender: false),
Chat(message: 'それは良かったです。', isSender: true),
Chat(message: 'ありがとうございます。', isSender: false),
Chat(message: 'どういたしまして。', isSender: true),
Chat(message: 'また話しましょう。', isSender: false),
Chat(message: 'こんにちは!今日はどんな一日でしたか?', isSender: true),
Chat(message: '今日はとても忙しかったですが、楽しかったです。', isSender: false),
Chat(message: 'それは良かったです。何をしましたか?', isSender: true),
Chat(message: '友達と会って、買い物に行きました。', isSender: false),
Chat(message: '楽しそうですね。何を買いましたか?', isSender: true),
Chat(message: '新しい服と本を買いました。', isSender: false),
Chat(message: '素敵ですね。どんな本を買いましたか?', isSender: true),
Chat(message: 'ミステリー小説を買いました。', isSender: false),
Chat(message: 'それは面白そうです。', isSender: true),
Chat(message: 'はい、とても楽しみです。', isSender: false),
Chat(message: 'また感想を聞かせてください。', isSender: true),
Chat(message: 'もちろんです。', isSender: false),
Chat(message: 'ありがとうございます。', isSender: true),
Chat(message: 'どういたしまして。', isSender: false),
Chat(message: 'また話しましょう。', isSender: true),
Chat(message: 'はい、またね。', isSender: false),
];
final TextEditingController _textController = TextEditingController();
final FocusNode _focusNode = FocusNode();
final ScrollController _scrollController = ScrollController();
bool _isTextFieldEnabled = false;

@override
void initState() {
super.initState();
_textController.addListener(() {
setState(() {
_isTextFieldEnabled = _textController.text.trim().isNotEmpty;
});
});
}

@override
void dispose() {
_textController.dispose();
_focusNode.dispose();
_scrollController.dispose();
super.dispose();
}

void _sendMessage() {
if (_textController.text.trim().isEmpty) return;

setState(() {
_chatList.insert(
0,
Chat(message: _textController.text.trim(), isSender: true),
);
});

_textController.clear();
_scrollToBottom();
}

void _showUserProfile() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (BuildContext context) {
return DraggableScrollableSheet(
expand: false,
initialChildSize: 0.9,
maxChildSize: 0.9,
minChildSize: 0.3,
builder: (BuildContext context, ScrollController scrollController) {
return UserProfile(scrollController: scrollController);
},
);
},
);
}

void _scrollToBottom() {
Future.delayed(const Duration(milliseconds: 0), () {
if (_scrollController.hasClients) {
_scrollController.animateTo(
0.0,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
toolbarOpacity: 1.0,
backgroundColor: Colors.grey[200], // WhatsApp-like blue
leading: GestureDetector(
onTap: () {
Navigator.pop(context);  // Back button logic
},
child: const Icon(Icons.arrow_back),
),
title: Row(
children: [
GestureDetector(
onTap: _showUserProfile,
child: const CircleAvatar(
backgroundImage: NetworkImage(
"https://i.pravatar.cc/150?img=2"), // Replace with dynamic avatar
),
),
const SizedBox(width: 10),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'userName',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
Text(
'userStatus',
style: TextStyle(
fontSize: 12,
color: Colors.black,
),
),
],
),
],
),
actions: [
IconButton(
icon: const Icon(Icons.call),
onPressed: () {},
),
IconButton(
icon: const Icon(Icons.videocam),
onPressed: () {},
),
IconButton(
icon: const Icon(Icons.more_vert),
onPressed: _showUserProfile,
),
],
),
body: Column(
children: [
Expanded(
child: GestureDetector(
onTap: () {
_focusNode.unfocus();
},
child: Align(
alignment: Alignment.topCenter,
child: ListView.separated(
reverse: true,
controller: _scrollController,
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
separatorBuilder: (_, __) =>  const SizedBox(height: 12),
itemCount: _chatList.length,
itemBuilder: (context, index) {
return _Bubble(chat: _chatList[index]);
},
),
),
),
),
_buildBottomInputField(),
],
),
);
}

Widget _buildBottomInputField() {
return SafeArea(
bottom: true,
child: Container(
constraints: const BoxConstraints(minHeight: 48),
width: double.infinity,
decoration: const BoxDecoration(
border: Border(
top: BorderSide(color: Color(0xFFE5E5EA)),
),
),
child: Stack(
children: [
TextField(
focusNode: _focusNode,
controller: _textController,
maxLines: null,
textAlignVertical: TextAlignVertical.top,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: const EdgeInsets.only(
right: 42,
left: 16,
top: 18,
),
hintText: 'Message',
enabledBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(8.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(8.0),
),
),
),
Positioned(
bottom: 0,
right: 0,
child: IconButton(
icon: Icon(
Icons.send,
color: _isTextFieldEnabled
? const Color(0xFF007AFF)
: const Color(0xFFBDBDC2),
),
onPressed: _isTextFieldEnabled ? _sendMessage : null,
),
),
],
),
),
);
}
}

class _Bubble extends StatelessWidget {
final Chat chat;

const _Bubble({required this.chat});

@override
Widget build(BuildContext context) {
return Align(
alignment: chat.isSender ? Alignment.centerRight : Alignment.centerLeft,
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 14),
decoration: BoxDecoration(
color:
chat.isSender ? const Color(0xFF007AFF) : const Color(0xFFE5E5EA),
borderRadius: BorderRadius.circular(16),
),
child: Text(
chat.message,
style: TextStyle(
color: chat.isSender ? Colors.white : Colors.black87,
),
),
),
);
}
}

class UserProfile extends StatelessWidget {
final ScrollController scrollController;

const UserProfile({required this.scrollController, super.key});

@override
Widget build(BuildContext context) {
return SingleChildScrollView(
controller: scrollController,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Center(
child: CircleAvatar(
radius: 50,
backgroundImage: NetworkImage(
'https://via.placeholder.com/150',
),
),
),
const SizedBox(height: 20),
const Center(
child: Text(
'John Doe',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 10),
const Center(
child: Text(
'A short description about the user goes here.  For example, their hobbies, likes, or interests.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, color: Colors.grey),
),
),
const SizedBox(height: 20),
const Text(
'Photos',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 5,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
'https://via.placeholder.com/100',
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
);
},
),
),
],
),
),
);
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post