在更新recyclerview android的textview项目时,Recyclerview滚动不顺畅

时间:2017-08-04 06:39:30

标签: android android-recyclerview

我的app recyclerview将audio,imageview,textview作为项目。滚动Recyclerview时,如果项目未更新,则滚动正确,没有任何问题。但是在播放recyclerview的音频项目时滚动recyclelerview并不流畅,它的行为与下面附加的gif图像相同。在播放音频时,我正在更新textview中的音频当前播放时间。我不确定这里有什么问题。请帮助我。感谢。

这是我的代码。

public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

ArrayList<SessionHistoryMesssage> messageArrayList;

MediaPlayer mPlayer = null;

LocalService mService;
boolean mBound = false;

private RelativeLayout.LayoutParams params;
int currentlyPlayingPosition = -1;
public String mBasePath = "", imageDirectory = "", mSessionId = "", audioDirectory = "";
private ProgressDialog progressDialog;

public RetrofitRestAdapter retrofitRestAdapter;
private MessageAdapter messageListAdapter;
private SessionHistoryResponse sessionHistoryResponse;
public Context mContext;
private int mSelectionPosition = -1;
private int num = 0;
public boolean isSessionStarted=false;

public static Handler mHandler;
public int playposition = -1, sessionstartPosition = -1,     alreadystartPosition = -1, sessionendPosition = -1;

public MessageAdapter(Context mContext
        , ArrayList<SessionHistoryMesssage> messageArrayList, String mBasePath) {

    this.mContext = mContext;
    this.messageArrayList = messageArrayList;
    this.mBasePath = mBasePath;

    mHandler = new Handler();

    Intent intent = new Intent(mContext, LocalService.class);
    this.mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

}

// 1. Type      a) SEND  b) RECEIVE
// 2. Message   a) AUDIO b) IMAGE

@Override
public int getItemViewType(int position) {
    // Just as an example, return 0 or 2 depending on position
    // Note that unlike in ListView adapters, types don't have to be contiguous

    Log.i("ViewType", messageArrayList.get(position).getmMediaType() + "");
    Log.i("sent by", messageArrayList.get(position).getmSentBy() + "");

    return Integer.parseInt(messageArrayList.get(position).getmSentBy());
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    VHItemAudio dataObjectHolder = null;

    if (Integer.parseInt(Utility.readPatientId(mContext)) == viewType) {

        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.layout_a_conversation_item, parent, false);
        dataObjectHolder = new VHItemAudio(view);

        return dataObjectHolder;

    } else {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.layout_b_conversation_item, parent, false);

        dataObjectHolder = new VHItemAudio(view);

        return dataObjectHolder;

    }
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {

    final VHItemAudio vhItemHolder = (VHItemAudio) holder;

    vhItemHolder.bind(messageArrayList.get(position), position);
   }

public class VHItemAudio extends RecyclerView.ViewHolder {

    ImageView playPauseImageView, imgDownloadAudio, imgDownloadImage;
    TextView txtImageSendTime, runningTimerTextView, txtAudioSendTime, txtSessionStart;
    SeekBar seekBar;
    ImageView imageView;
    RelativeLayout layoutAudio, layoutImage, layoutdownloadImage, layoutSessionStart;
    ProgressBar progressImageDownload, progressAudioDownload;


    private ImageView imageShareImageView,recordAudioImageView,imgEndSession;

    public VHItemAudio(View itemView) {
        super(itemView);

        playPauseImageView = (ImageView) itemView.findViewById(R.id.playPauseImageView);
        txtImageSendTime = (TextView) itemView.findViewById(R.id.txtImageSendTime);
        runningTimerTextView = (TextView) itemView.findViewById(R.id.runningTimerTextView);
        seekBar = (SeekBar) itemView.findViewById(R.id.seekBar);
        imgDownloadAudio = (ImageView) itemView.findViewById(R.id.imgDownloadAudio);
        imgDownloadImage = (ImageView) itemView.findViewById(R.id.imgDownloadImage);
        imageView = (ImageView) itemView.findViewById(R.id.imageView);
        txtAudioSendTime = (TextView) itemView.findViewById(R.id.txtAudioSendTime);
        layoutAudio = (RelativeLayout) itemView.findViewById(R.id.layoutAudio);
        layoutImage = (RelativeLayout) itemView.findViewById(R.id.layoutImage);
        layoutdownloadImage = (RelativeLayout) itemView.findViewById(R.id.layoutdownloadImage);
        progressImageDownload = (ProgressBar) itemView.findViewById(R.id.progressImageDownload);
        progressAudioDownload = (ProgressBar) itemView.findViewById(R.id.progressAudioDownload);
        layoutSessionStart = (RelativeLayout) itemView.findViewById(R.id.layoutSessionStart);
        txtSessionStart = (TextView) itemView.findViewById(R.id.txtSessionStart);

        Log.i("", "Adding Listener");


        imageShareImageView= (ImageView) ((PatientActivity)PatientActivity.patientContext).findViewById(R.id.imageShareImageView);
        recordAudioImageView= (ImageView) ((PatientActivity) PatientActivity.patientContext).findViewById(R.id.recordAudioImageView);
        imgEndSession= (ImageView) ((PatientActivity) PatientActivity.patientContext).findViewById(R.id.imgEndSession);

    }


    public void bind(final SessionHistoryMesssage sessionHistoryMesssage, final int position) {

        if (sessionHistoryMesssage.getmSessionStart().equalsIgnoreCase("yes")
                && Integer.parseInt(sessionHistoryMesssage.getmTransToId())
                == Integer.parseInt(Utility.readPatientId(mContext))) {

            sessionstartPosition = position;
            isSessionStarted=true;

        } else if (sessionHistoryMesssage.getmSessionStart().equalsIgnoreCase("already started")) {

            alreadystartPosition = position;

        } else if (sessionHistoryMesssage.getmSessionStart().equalsIgnoreCase("end")) {

            sessionendPosition = position;

        } else {

        }

        if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("audio")) {



            layoutAudio.setVisibility(View.VISIBLE);
            layoutImage.setVisibility(View.GONE);

            seekBar.setFocusable(false);

            txtAudioSendTime.setText(Utility.convertDateTime(sessionHistoryMesssage.getmSentTime()));

            audioDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/A/Audio/";

            File file = new File(Environment.getExternalStorageDirectory()
                    + "/A/Audio/" + messageArrayList.get(position).getmMediaValue());

            if (file.exists()) {

                imgDownloadAudio.setVisibility(View.GONE);
                playPauseImageView.setVisibility(View.VISIBLE);
                playPauseImageView.setImageResource(R.drawable.play_icon);

            } else {

                imgDownloadAudio.setVisibility(View.VISIBLE);
                playPauseImageView.setVisibility(View.GONE);

                imgDownloadAudio.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        imgDownloadAudio.setVisibility(View.GONE);

                        Log.v("basepath", mBasePath);

                        new DownloadFile(mBasePath + messageArrayList.get(position).getmMediaPath() +
                                messageArrayList.get(position).getmMediaValue(),
                                audioDirectory + messageArrayList.get(position).getmMediaValue()
                                , imgDownloadAudio, progressAudioDownload).execute();
                    }
                });

            }

            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                    if (playposition == position) {
                        int seekBarPosition = seekBar.getProgress();
                        mPlayer.seekTo(seekBarPosition);
                    }
                }
            });

            playPauseImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    if (!mService.isPlaying()) {

                        playposition = position;
                        mService.playAudio(audioDirectory + messageArrayList.get(position).getmMediaValue());
                        notifyDataSetChanged();

                    } else {

                        if (playposition == position) {
                            playposition = -1;
                            mHandler.removeCallbacks(null);
                            mService.stopAudio();
                            notifyDataSetChanged();
                        } else {
                            playposition = position;
                            mService.playAudio(audioDirectory + messageArrayList.get(position).getmMediaValue());
                            notifyDataSetChanged();
                        }
                    }

                }
            });

        } else if (messageArrayList.get(position).getmMediaType().equalsIgnoreCase("photo")) {

            layoutImage.setVisibility(View.VISIBLE);
            layoutAudio.setVisibility(View.GONE);

            txtImageSendTime.setText(Utility.convertDateTime(messageArrayList.get(position).getmSentTime()));

            imageDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/A/Image/";

            Log.v("image path123", mBasePath + messageArrayList.get(position).getmMediaPath()
                    + messageArrayList.get(position).getmMediaValue());

            try {

                File file = new File(Environment.getExternalStorageDirectory()
                        + "/A/Image/" + messageArrayList.get(position).getmMediaValue());



                if (!file.exists()) {
                    layoutdownloadImage.setVisibility(View.VISIBLE);
                    imageView.setVisibility(View.GONE);
                } else {
                    layoutdownloadImage.setVisibility(View.GONE);
                    imageView.setVisibility(View.VISIBLE);
                    imageView.setImageBitmap(BitmapFactory.decodeFile(file.getAbsolutePath()));
                }

                layoutdownloadImage.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        mSessionId = messageArrayList.get(position).getmSessionId();
                        imgDownloadImage.setVisibility(View.GONE);

                        new DownloadImage(mBasePath + messageArrayList.get(position).getmMediaPath()
                                + sessionHistoryMesssage.getmMediaValue(),
                                sessionHistoryMesssage.getmMediaValue(),
                                imgDownloadImage, progressImageDownload
                        ).execute();
                    }
                });

                imageView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        showImageDialog(position);
                    }
                });


            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        if (sessionstartPosition == position) {

                layoutSessionStart.setVisibility(View.VISIBLE);
                layoutAudio.setVisibility(View.GONE);
                layoutImage.setVisibility(View.GONE);

            txtSessionStart.setText("Start session");

            if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("audio")) {
                params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
                params.addRule(RelativeLayout.BELOW, R.id.layoutAudio);
            } else if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("photo")) {
                params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
                params.addRule(RelativeLayout.BELOW, R.id.layoutImage);
            } else {

            }

            if(!isSessionStarted) {
                imageShareImageView.setVisibility(View.GONE);
                recordAudioImageView.setVisibility(View.GONE);
                imgEndSession.setVisibility(View.GONE);
                isSessionStarted=true;
            }


            txtSessionStart.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    retrofitRestAdapter = new RetrofitRestAdapter();

                    Map<String, String> sessionstartParams = new HashMap<String, String>();
                    sessionstartParams.put("session_id", sessionHistoryMesssage.getmSessionId());
                    final ProgressDialog progressDialog = new ProgressDialog(mContext);
                    progressDialog.setTitle("Please wait...");
                    progressDialog.show();

                    retrofitRestAdapter.sessionStart(sessionstartParams, new Callback<SessionHistoryResponse>() {
                        @Override
                        public void onResponse(Call<SessionHistoryResponse> call, Response<SessionHistoryResponse> response) {

                            Log.v("session start response", new Gson().toJson(response.body()));
                            progressDialog.dismiss();
                            txtSessionStart.setEnabled(false);
                            txtSessionStart.setClickable(false);

                            imageShareImageView.setVisibility(View.VISIBLE);
                            recordAudioImageView.setVisibility(View.VISIBLE);
                            imgEndSession.setVisibility(View.VISIBLE);
                        }

                        @Override
                        public void onFailure(Call<SessionHistoryResponse> call, Throwable t) {

                            t.printStackTrace();
                            progressDialog.dismiss();
                            imageShareImageView.setVisibility(View.GONE);
                            recordAudioImageView.setVisibility(View.GONE);
                            imgEndSession.setVisibility(View.GONE);
                        }
                    });

                }
            });
        } else {

        }

        if (position == alreadystartPosition) {
            layoutSessionStart.setClickable(false);
            txtSessionStart.setClickable(false);
            imageShareImageView.setVisibility(View.VISIBLE);
            recordAudioImageView.setVisibility(View.VISIBLE);
            imgEndSession.setVisibility(View.VISIBLE);
        } else {

        }

        if (position == sessionendPosition) {

            layoutSessionStart.setClickable(false);
            txtSessionStart.setClickable(false);
           // layoutSessionStart.setVisibility(View.VISIBLE);
            txtSessionStart.setText("End session");

            if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("audio")) {
                params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
                params.addRule(RelativeLayout.BELOW, R.id.layoutAudio);
            } else if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("photo")) {
                params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
                params.addRule(RelativeLayout.BELOW, R.id.layoutImage);
            } else {

            }

            imageShareImageView.setVisibility(View.GONE);
            recordAudioImageView.setVisibility(View.GONE);
            imgEndSession.setVisibility(View.GONE);
        } else {

        }


        if (position == playposition) {
            if (mBound) {

                Log.v("service", "bound");

                mHandler.removeCallbacks(null);

                seekBar.setMax(mService.getrunningTime() / 1000);

                Log.v("duration", mService.getrunningTime() + "");
                playPauseImageView.setImageResource(R.drawable.stop_icon);

                ((PatientActivity) mContext).runOnUiThread(new Runnable() {

                    @Override
                    public void run() {

                        if (mService.isPlaying()) {

                            num = mService.getDuration();
                            seekBar.setProgress(num / 1000);
                            runningTimerTextView.setText(convertMilliToMinutes(num));
                            //                            vhItemHolder.seekBar.setFocusable(false);
                            mHandler.postDelayed(this, 50);

                        } else {
                            playposition = -1;
                            mHandler.removeCallbacks(null);
                            seekBar.setProgress(0);
                            seekBar.setFocusable(false);
                            runningTimerTextView.setText("00:00");
                            playPauseImageView.setImageResource(R.drawable.play_icon);

                        }


                    }
                });
            } else {
                Log.v("service", "not bound");
            }

        } else {

            mHandler.removeCallbacks(null);
            playPauseImageView.setImageResource(R.drawable.play_icon);
            runningTimerTextView.setText("00:00");

            seekBar.setMax(0);
        }


    }
}

服务类

public class LocalService extends Service {

boolean mBound = false;

private final IBinder mBinder = new LocalBinder();
private int timer;

private MediaPlayer mediaPlayer = new MediaPlayer();
private boolean isStopped = true;
// Random number generator

/**
 * Class used for the client Binder.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with IPC.
 */
public class LocalBinder extends Binder {

    public LocalService getService() {
        // Return this instance of LocalService so clients can call public methods

        return LocalService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {

    return mBinder;
}

public int getrunningTime() {

    return mediaPlayer.getDuration();
}

public int getDuration() {
    // Log.v("player duration",timer+"");
    if (mediaPlayer != null) {
        if (!isStopped) {
            Log.v("playing", (mediaPlayer.getCurrentPosition()) + "");
            return mediaPlayer.getCurrentPosition();
        } else {
             //      mediaPlayer.reset();
            mHandler.removeCallbacks(null);
            return 0;

        }
    } else {
        Log.v("not playing", (mediaPlayer.getCurrentPosition()) + "");
        mHandler.removeCallbacks(null);
        return 0;
    }
}

@Override
public void onCreate() {
    super.onCreate();
    mediaPlayer = new MediaPlayer();

    try {

        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {

                isStopped = false;
                //playAudio();

                Log.v("max duration", timer + "");

            }
        });

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {

                //mediaPlayer.stop();
                isStopped = true;
                mediaPlayer.reset();
                //mediaPlayer.release();
            }
        });


    } catch (Exception e) {
        e.printStackTrace();
    }

}

public boolean isPlaying() {
    if (mediaPlayer != null) {
        try {
            if (mediaPlayer.isPlaying()) {
                return true;
            } else {
                return false;
            }


        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    } else {
        return false;
    }
}

public void playAudio(String path) {

    Log.v("audio path",path);
    if (mediaPlayer.isPlaying()) {
        mediaPlayer.stop();
    }

    mediaPlayer.reset();

    try {
        mediaPlayer.setDataSource(path);
        mediaPlayer.prepare();
        mediaPlayer.start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void stopAudio() {

    if (mediaPlayer != null) {
        mediaPlayer.stop();
        //  mediaPlayer.reset();
        isStopped = true;
    }

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    return START_STICKY;
}

@Override
public void unbindService(ServiceConnection conn) {
    super.unbindService(conn);

    mediaPlayer.reset();
    mediaPlayer.release();
}


@Override
public void onDestroy() {
    super.onDestroy();
    mediaPlayer.reset();
    mediaPlayer.release();

  }
}

enter image description here

2 个答案:

答案 0 :(得分:0)

因为您正在调用notifyDataSetChanged(),并且只要您这样做,它就会更新整个recyclerview。您最好调用notifyItemChanged(position)来更新您应该更新的特定项目。

((PatientActivity) mContext).runOnUiThread(new Runnable() {

                    @Override
                    public void run() {

                        if (mService.isPlaying()) {

                            num = mService.getDuration();
                            seekBar.setProgress(num / 1000);
                            runningTimerTextView.setText(convertMilliToMinutes(num));
                            //                            vhItemHolder.seekBar.setFocusable(false);
                            mHandler.postDelayed(this, 50);

                        } else {
                            playposition = -1;
                            mHandler.removeCallbacks(null);
                            seekBar.setProgress(0);
                            seekBar.setFocusable(false);
                            runningTimerTextView.setText("00:00");
                            playPauseImageView.setImageResource(R.drawable.play_icon);

                        }


                    }
                });

你可以把它转换成类似的东西。

if (position == playposition) {
            if (mBound) {

                Log.v("service", "bound");

                mHandler.removeCallbacks(null);

                seekBar.setMax(mService.getrunningTime() / 1000);

                Log.v("duration", mService.getrunningTime() + "");
                playPauseImageView.setImageResource(R.drawable.stop_icon);


                        if (mService.isPlaying()) {

                            num = mService.getDuration();
                            seekBar.setProgress(num / 1000);
                            runningTimerTextView.setText(convertMilliToMinutes(num));
                            //                            vhItemHolder.seekBar.setFocusable(false);
                           notifyItemChanged(position);

                        } else {
                            playposition = -1;
                            mHandler.removeCallbacks(null);
                            seekBar.setProgress(0);
                            seekBar.setFocusable(false);
                            runningTimerTextView.setText("00:00");
                            playPauseImageView.setImageResource(R.drawable.play_icon);
notifyItemChanged(position);
                        }




            }
}

尝试删除runnable的全部用法。

答案 1 :(得分:0)

setHasStableIds(真);在适配器构造函数中添加它,并在适配器中覆盖这两个方法。

@Override
public long getItemId(int pos) {
            return pos;
}

@Override
public int getItemViewType(int pos) {
       //return pos;
return Integer.parseInt(messageArrayList.get(position).getmSentBy());
}

它可能对你有帮助......