Java 媒体播放器播放时,Recyclerview正在滚动。我怎样才能修好它?
我正在开发一款具有语音信息功能的聊天应用程序。这些音频信息的录制和播放效果非常好,但是如果我点击播放按钮,Recyclerview就会向上滚动。有人有主意吗 对不起,我英语不好,我来自德国;) AdapterChat.JavaJava 媒体播放器播放时,Recyclerview正在滚动。我怎样才能修好它?,java,android,firebase,android-recyclerview,Java,Android,Firebase,Android Recyclerview,我正在开发一款具有语音信息功能的聊天应用程序。这些音频信息的录制和播放效果非常好,但是如果我点击播放按钮,Recyclerview就会向上滚动。有人有主意吗 对不起,我英语不好,我来自德国;) AdapterChat.Java private static final int MSG_TYPE_LEFT = 0; private static final int MSG_TYPE_RIGHT = 1; Context context; List<ModelChat> chatList
private static final int MSG_TYPE_LEFT = 0;
private static final int MSG_TYPE_RIGHT = 1;
Context context;
List<ModelChat> chatList;
String imageUrl;
FirebaseUser fUser;
public AdapterChat(Context context, List<ModelChat> chatList, String imageUrl) {
this.context = context;
this.chatList = chatList;
this.imageUrl = imageUrl;
}
@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
//inflate layouts: row_chat_left.xml for receiver, row_chat_right.xml for sender
if (i == MSG_TYPE_RIGHT) {
View view = LayoutInflater.from(context).inflate(R.layout.row_chat_right, viewGroup, false);
return new MyHolder(view);
}
else {
View view = LayoutInflater.from(context).inflate(R.layout.row_chat_left, viewGroup, false);
return new MyHolder(view);
}
}
public void add(ModelChat object) {
chatList.add(object);
add(object);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onBindViewHolder(@NonNull final MyHolder myHolder, final int i) {
final String message = chatList.get(i).getMessage();
String timeStamp = chatList.get(i).getTimestamp();
String type = chatList.get(i).getType();
if (type.equals("text") || message.equals(R.string.message_was_deleted)) {
//text message
myHolder.messageTv.setVisibility(View.VISIBLE);
myHolder.messageIv.setVisibility(View.GONE);
myHolder.playAudioBtn.setVisibility(View.GONE);
myHolder.messageVoiceSb.setVisibility(View.GONE);
myHolder.sbCurrentTime.setVisibility(View.GONE);
myHolder.sbTotalDuration.setVisibility(View.GONE);
myHolder.messageTv.setText(message);
}
else if (type.equals("audio")) {
//audio message
myHolder.messageTv.setVisibility(View.GONE);
myHolder.messageIv.setVisibility(View.GONE);
myHolder.playAudioBtn.setVisibility(View.VISIBLE);
myHolder.messageVoiceSb.setVisibility(View.VISIBLE);
myHolder.sbCurrentTime.setVisibility(View.VISIBLE);
myHolder.sbTotalDuration.setVisibility(View.VISIBLE);
myHolder.voiceMessageUrl = message;
myHolder.getAdapterPosition();
myHolder.playAudioBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (myHolder.mediaPlayer.isPlaying()) {
myHolder.handler.removeCallbacks(myHolder.updater);
myHolder.mediaPlayer.pause();
myHolder.playAudioBtn.setImageResource(R.drawable.ic_play_btn);
}
else {
myHolder.mediaPlayer.start();
myHolder.playAudioBtn.setImageResource(R.drawable.ic_pause_btn);
myHolder.updateSeekbar();
}
}
});
myHolder.prepareMediaPlayer();
myHolder.messageVoiceSb.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
SeekBar seekBar = (SeekBar) view;
int playPosition = (myHolder.mediaPlayer.getDuration() / 100) * seekBar.getProgress();
myHolder.mediaPlayer.seekTo(playPosition);
myHolder.sbCurrentTime.setText(myHolder.milliSecondsToTimer(myHolder.mediaPlayer.getCurrentPosition()));
return false;
}
});
myHolder.mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
myHolder.messageVoiceSb.setSecondaryProgress(i);
}
});
myHolder.mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
myHolder.messageVoiceSb.setProgress(0);
myHolder.playAudioBtn.setImageResource(R.drawable.ic_play_btn);
myHolder.mediaPlayer.reset();
myHolder.prepareMediaPlayer();
}
});
}
else {
//image message
myHolder.messageIv.setVisibility(View.VISIBLE);
myHolder.messageTv.setVisibility(View.GONE);
myHolder.playAudioBtn.setVisibility(View.GONE);
myHolder.messageVoiceSb.setVisibility(View.GONE);
myHolder.sbCurrentTime.setVisibility(View.GONE);
myHolder.sbTotalDuration.setVisibility(View.GONE);
Picasso.get().load(message).placeholder(R.drawable.ic_image_black).into(myHolder.messageIv);
}
//set data
myHolder.messageTv.setText(message);
myHolder.timeTv.setText(timeStamp);
try {
Picasso.get().load(imageUrl).into(myHolder.profileIv);
}
catch (Exception e) {
}
myHolder.messageLayout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//show delete message confirm dialog
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.delete);
builder.setMessage("Are you sure to delete this message?");
//delete button
builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
deleteMessage(i);
}
});
//cancel delete button
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//dismiss dialog
dialog.dismiss();
}
});
//create and show dialog
builder.create().show();
return false;
}
});
//set seen/delivered status of message
if (i==chatList.size()-1) {
if (chatList.get(i).isSeen()) {
myHolder.isSeenTv.setText("Seen");
}
else {
myHolder.isSeenTv.setText("Delivered");
}
}
else {
myHolder.isSeenTv.setVisibility(View.GONE);
}
}
private void deleteMessage(int position) {
final String myUID = FirebaseAuth.getInstance().getCurrentUser().getUid();
/*Logic:
* Get timeStamp of clicked message
* Compare the timeStamp of the clicked message with all messages in CHats
* Where both values matches, delete that message
* This will allow sender to delete his and receiver's message*/
String msgTimeStamp = chatList.get(position).getTimestamp();
final String type = chatList.get(position).getType();
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("Chats");
Query query = dbRef.orderByChild("timestamp").equalTo(msgTimeStamp);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()) {
/*if you want to allow sender to delete only his message then
* compare sender value with current user's uid
* if they match means its the message of sender that is trying to delete*/
if (ds.child("sender").getValue().equals(myUID)) {
if (type.equals("audio")) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("type", "text");
ds.getRef().updateChildren(hashMap);
} else if (type.equals("image")) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("type", "text");
ds.getRef().updateChildren(hashMap);
}
/*We can do one of two things here
* 1) Remove the message from chats
* 2) Set the value of message "This messages was deleted..." */
//1) Remove the message from Chats
//ds.getRef().removeValue();
//2) Set the value of message "This message was deleted..."
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("message", "This message was deleted...");
ds.getRef().updateChildren(hashMap);
Toast.makeText(context, "message deleted...", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(context, "You can delete only your messages...", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@Override
public int getItemCount() {
return chatList.size();
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public int getItemViewType(int position) {
//get currently signed in user
fUser = FirebaseAuth.getInstance().getCurrentUser();
if (chatList.get(position).getSender().equals(fUser.getUid())) {
return MSG_TYPE_RIGHT;
}
else {
return MSG_TYPE_LEFT;
}
}
//view holder class
class MyHolder extends RecyclerView.ViewHolder {
//views
ImageView profileIv, messageIv;
ImageButton playAudioBtn;
SeekBar messageVoiceSb;
TextView messageTv, timeTv, isSeenTv, sbCurrentTime, sbTotalDuration;
LinearLayout messageLayout; //for click listener to show delete option
MediaPlayer mediaPlayer;
Handler handler = new Handler();
String voiceMessageUrl = null;
@SuppressLint("ClickableViewAccessibility")
public MyHolder(@NonNull View itemView) {
super(itemView);
//init views
profileIv = itemView.findViewById(R.id.profileIv);
messageIv = itemView.findViewById(R.id.messageIV);
messageTv = itemView.findViewById(R.id.messageTv);
messageVoiceSb = itemView.findViewById(R.id.messageVoiceSb);
playAudioBtn = itemView.findViewById(R.id.playAudioBtn);
sbCurrentTime = itemView.findViewById(R.id.sbCurrentTime);
sbTotalDuration = itemView.findViewById(R.id.sbTotalDuration);
timeTv = itemView.findViewById(R.id.timeTv);
isSeenTv = itemView.findViewById(R.id.isSeenTv);
messageLayout = itemView.findViewById(R.id.messageLayout);
mediaPlayer = new MediaPlayer();
messageVoiceSb.setMax(100);
}
private void prepareMediaPlayer() {
try {
mediaPlayer.setDataSource(voiceMessageUrl); //url of audio file to play
mediaPlayer.prepare();
sbTotalDuration.setText(milliSecondsToTimer(mediaPlayer.getDuration()));
} catch (Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private Runnable updater = new Runnable() {
@Override
public void run() {
updateSeekbar();
long currentDuration = mediaPlayer.getCurrentPosition();
sbCurrentTime.setText(milliSecondsToTimer(currentDuration));
}
};
private void updateSeekbar() {
if (mediaPlayer.isPlaying()) {
messageVoiceSb.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration()) * 100));
handler.postDelayed(updater, 1000);
}
}
private String milliSecondsToTimer(long milliSeconds) {
String timerString = "";
String secondsString;
int hours = (int) (milliSeconds / (1000 * 60 * 60));
int minutes = (int) (milliSeconds % (1000 * 60 * 60)) / (1000 * 60);
int seconds = (int) ((milliSeconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
if (hours > 0) {
timerString = hours + ":";
}
if (seconds < 10) {
secondsString = "0" + seconds;
} else {
secondsString = "" + seconds;
}
timerString = timerString + minutes + ":" + secondsString;
return timerString;
}
}
private static final int MSG_TYPE_LEFT=0;
私有静态final int MSG_TYPE_RIGHT=1;
语境;
列表聊天列表;
字符串imageUrl;
FirebaseUser定影器;
PublicAdapterChat(上下文上下文、列表聊天列表、字符串图像URL){
this.context=上下文;
this.chatList=聊天列表;
this.imageUrl=imageUrl;
}
@非空
@凌驾
public MyHolder onCreateViewHolder(@NonNull ViewGroup ViewGroup,int i){
//充气布局:接收端为row_chat_left.xml,发送端为row_chat_right.xml
如果(i==MSG\u TYPE\u RIGHT){
视图=布局更平坦。从(上下文)。充气(R.layout.row\u chat\u right,viewGroup,false);
返回新的MyHolder(视图);
}
否则{
视图=布局更平坦。从(上下文)。充气(R.layout.row\u chat\u left,viewGroup,false);
返回新的MyHolder(视图);
}
}
公共void添加(ModelChat对象){
添加(对象);
添加(对象);
}
@SuppressLint(“ClickableViewAccessibility”)
@凌驾
public void onBindViewHolder(@NonNull final MyHolder MyHolder,final int i){
最后一个字符串message=chatList.get(i).getMessage();
String timeStamp=chatList.get(i).getTimestamp();
字符串类型=chatList.get(i).getType();
if(type.equals(“text”)| message.equals(R.string.message_已删除)){
//短信
myHolder.messageTv.setVisibility(View.VISIBLE);
myHolder.messageIv.setVisibility(View.GONE);
myHolder.playardobtn.setVisibility(View.GONE);
myHolder.messageVoiceSb.setVisibility(View.GONE);
myHolder.sbCurrentTime.setVisibility(View.GONE);
myHolder.sbTotalDuration.setVisibility(View.GONE);
myHolder.messageTv.setText(message);
}
else if(键入等于(“音频”)){
//音频信息
myHolder.messageTv.setVisibility(View.GONE);
myHolder.messageIv.setVisibility(View.GONE);
myHolder.playardobtn.setVisibility(View.VISIBLE);
myHolder.messageVoiceSb.setVisibility(View.VISIBLE);
myHolder.sbCurrentTime.setVisibility(View.VISIBLE);
myHolder.sbTotalDuration.setVisibility(View.VISIBLE);
myHolder.voiceMessageUrl=消息;
myHolder.getAdapterPosition();
myHolder.playAudioBtn.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
if(myHolder.mediaPlayer.isPlaying()){
myHolder.handler.removeCallbacks(myHolder.updater);
myHolder.mediaPlayer.pause();
myHolder.playAudioBtn.setImageResource(R.drawable.ic_play_btn);
}
否则{
myHolder.mediaPlayer.start();
myHolder.playardobtn.setImageResource(R.drawable.ic\u pause\u btn);
myHolder.updateSeekbar();
}
}
});
myHolder.prepareMediplayer();
myHolder.messageVoiceSb.setOnTouchListener(新视图.OnTouchListener()){
@凌驾
公共布尔onTouch(视图、运动事件、运动事件){
SeekBar SeekBar=(SeekBar)视图;
int playPosition=(myHolder.mediaPlayer.getDuration()/100)*seekBar.getProgress();
myHolder.mediaPlayer.seekTo(playPosition);
myHolder.sbCurrentTime.setText(myHolder.毫秒计时器(myHolder.mediaPlayer.getCurrentPosition());
返回false;
}
});
myHolder.mediaPlayer.setOnBufferingUpdateListener(新的mediaPlayer.OnBufferingUpdateListener(){
@凌驾
public void onBufferingUpdate(MediaPlayer MediaPlayer,int i){
myHolder.messageVoiceSb.SetSecondary程序(i);
}
});
myHolder.mediaPlayer.setOnCompletionListener(新的mediaPlayer.OnCompletionListener(){
@凌驾
完成时的公共作废(MediaPlayer MediaPlayer){
myHolder.messageVoiceSb.setProgress(0);
myHolder.playAudioBtn.setImageResource(R.drawable.ic_play_btn);
myHolder.mediaPlayer.reset();
myHolder.prepareMediplayer();
}
});
}
否则{
//图像信息
myHolder.messageIv.setVisibility(View.VISIBLE);
myHolder.messageTv.setVisibility(View.GONE);
myHolder.playardobtn.setVisibility(View.GONE);
myHolder.messageVoiceSb.setVisibility(View.GONE);
myHolder.sbCurrentTime.setVisibility(View.GONE);
myHolder.sbTotalDuration.setVisibility(View.GONE);
Picasso.get().load(message).placeholder(R.drawable.ic_image_black).into(myHolder.messageIv);
}
//设置数据
myHolder.messageTv.setText(message);
myHolder.timeTv.setText(时间戳);
试一试{
Picasso.get().load(imageUrl).into(myHolder.profileIv);
}
捕获(例外e){
}
myHolder.messageLayout.setOnLongClickListener(新视图。OnLongClickListener(){
@凌驾
仅长按公共布尔值(视图v){
//显示删除消息确认对话框
AlertDialog.Builder=新建AlertDialog.Builder(上下文);
builder.setTitle(R.string.delete);
setMessage(“您确定要删除此邮件吗?”);
//删除按钮
setPositiveButton(R.string.delete,new DialogInterface.OnClickListener(){
@凌驾
public void onClick(DialogInterface dialog,int which){
删除消息(i);
}
});
//取消删除按钮
builder.set
<RelativeLayout 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:background="@color/chatBackground"
tools:context=".ChatActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="@color/colorPrimaryDark"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/profileIv"
android:layout_width="35dp"
android:layout_height="35dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_default"
app:civ_circle_background_color="@color/colorPrimaryDark"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_marginStart="20dp">
<!-- Receiver Name-->
<TextView
android:id="@+id/nameTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="His Name"
android:textColor="@color/colorWhite"
android:textSize="18sp"
android:textStyle="bold" />
<!-- Receiver Status i.e online or offline-->
<TextView
android:id="@+id/userStatusTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="online"
android:textColor="@color/colorWhite"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="@+id/blockIv"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:src="@drawable/ic_unblocked_green"
android:visibility="invisible"/>
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
<!-- RecyclerView-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chat_recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
android:layout_above="@id/chatLayout" />
<!-- send message edit text and button in layout-->
<LinearLayout
android:id="@+id/chatLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:background="@color/textInputBackground"
android:orientation="horizontal">
<!-- ImageButton: to send Image-->
<ImageButton
android:id="@+id/attachBtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@null"
android:src="@drawable/ic_attach_black" />
<!-- EditText: input message-->
<EditText
android:id="@+id/messageEt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:inputType="textCapSentences|textMultiLine"
android:padding="15dp"
android:hint="Start typing" />
<Chronometer
android:id="@+id/record_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textSize="14sp"
android:textColor="@color/colorPrimary" />
<!-- Button: voice message-->
<ImageButton
android:id="@+id/recordBtn"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@null"
android:src="@drawable/ic_record_btn_stopped" />
<!-- Button: send message-->
<ImageButton
android:id="@+id/sendBtn"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@null"
android:src="@drawable/ic_send" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="@+id/messageLayout"
android:padding="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="end">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/profileIv"
app:civ_border_color="@null"
android:visibility="gone"
android:src="@drawable/ic_default_img" />
<TextView
android:id="@+id/messageTv"
android:layout_weight="1"
android:textSize="16sp"
android:textColor="@color/textColor"
android:background="@drawable/bg_sender"
android:padding="15dp"
android:text="His Message"
android:visibility="gone"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/messageIV"
android:layout_width="200dp"
android:layout_height="200dp"
android:adjustViewBounds="true"
android:padding="15dp"
android:src="@drawable/ic_image_black"
android:scaleType="fitCenter"
android:background="@drawable/bg_sender" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_sender"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/playAudioBtn"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:background="@null"
android:src="@drawable/ic_play_btn" />
<SeekBar
android:id="@+id/messageVoiceSb"
android:visibility="gone"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/playAudioBtn"
android:padding="10dp"
android:layout_marginTop="10dp"
android:max="100"
android:progress="0" />
<TextView
android:id="@+id/sbCurrentTime"
android:visibility="gone"
android:text="0:00"
android:textStyle="bold"
android:textSize="12sp"
android:layout_marginStart="2dp"
android:layout_below="@id/messageVoiceSb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/sbTotalDuration"
android:visibility="gone"
android:textStyle="bold"
android:text="0:10"
android:textSize="12sp"
android:layout_below="@id/messageVoiceSb"
android:layout_toEndOf="@id/messageVoiceSb"
android:layout_marginEnd="12dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
<TextView
android:id="@+id/timeTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textAlignment="textEnd"
android:text="07/08/2020 23:00PM"
android:textColor="@color/textColor"
android:textSize="12sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/isSeenTv"
android:gravity="end"
android:textAlignment="textEnd"
android:text="delivered" />
<TextView
android:layout_width="match_parent" <-- This is what I changed
android:layout_height="wrap_content"/>
<SeekBar
android:layout_width="match_parent" <-- Check this as well
android:layout_height="wrap_content"/>