我正在构建一个音乐播放器应用并使用RecyclerView
。当我从列表中选择一首歌曲时,文本(歌曲名称)开始水平滚动。
如果我然后垂直滚动,要查找列表中的其他歌曲,然后滚动回正在播放的歌曲,水平滚动已停止,这是不希望的。
当我按下列表中的项目时,我将该视图保存在实例变量中(以后在更改歌曲时使用)并设置hasTransientState(true)
。
水平滚动的视图(ScrollTextView)是自定义的。
按下某个项目时会调用方法playPauseStop
。
对我而言,即使我在按下的视图上设置hasTransientState(true)
,我的adapater-class中的onBindViewHolder也会被调用。
我设法使用ListView
定期setHasTransientState(true)
来避免此问题,但是
如何使用RecyclerView
来避免此问题?
非常感谢任何帮助。
public class TrackListFragment extends Fragment {
private Context mContext;
private RecyclerView mRecyclerView;
private TrackAdapter mTrackAdapter;
private IPlayer mPlayer;
private int mCurrentTrack = -1;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
mPlayer = new Player(context);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recycler_view_layout, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
//mRecyclerView.getRecycledViewPool().setMaxRecycledViews(0, 3);
Bundle bundle = getArguments();
ArrayList<Track> tracks = null;
if (bundle != null) {
tracks = bundle.getParcelableArrayList("Tracks");
}
mTrackAdapter = new TrackAdapter(tracks, mContext);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mTrackAdapter);
mRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(mContext, mRecyclerView, new RecyclerTouchListener.IClickListener() {
@Override
public void onClick(View view, int position) {
playPauseStop(view, position);
}
@Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
private ScrollTextView mStv;
private RelativeLayout mRelativeLayout;
/**
* mCurrentTrack is initially -1,
* and set to -1 when media player is stopped.
* @param position
*/
public void playPauseStop(View view, int position) {
int firstViewItemIndex = ((LinearLayoutManager)mRecyclerView.getLayoutManager()).findFirstVisibleItemPosition();
int screenIndex = position - firstViewItemIndex;
ScrollTextView stv = null;
RelativeLayout relativeLayout = (RelativeLayout)mRecyclerView.getChildAt(screenIndex);
for(int i = 0; i < 2; i++) {
if(relativeLayout.getChildAt(i) instanceof ScrollTextView) {
stv = (ScrollTextView) relativeLayout.getChildAt(i);
}
}
if(mCurrentTrack == position && mPlayer.isPlaying()) {
mPlayer.pause();
stv.pauseScroll();
} else if(mCurrentTrack == position && !mPlayer.isPlaying()) {
// Start after pause
mPlayer.play();
stv.resumeScroll();
} else if(mCurrentTrack != position && mPlayer.isPlaying()) {
// Stop playing track
mPlayer.stop();
// Start new track
mPlayer = new Player(mContext);
String itemData = mTrackAdapter.getItem(position);
mPlayer.startPlayThread(itemData);
mStv.stopScrolling();
mStv.setTextColor(Color.BLUE);
mRelativeLayout.setHasTransientState(false);
mStv = stv;
stv.startScroll();
stv.setTextColor(Color.RED);
relativeLayout.setHasTransientState(true);
mRelativeLayout = relativeLayout;
mCurrentTrack = position;
}
if(mCurrentTrack == -1) { // Initial. Start first track.
mStv = stv;
mCurrentTrack = position;
String itemData = mTrackAdapter.getItem(position);
mPlayer.startPlayThread(itemData);
stv.startScroll();
stv.setTextColor(Color.RED);
relativeLayout.setHasTransientState(true);
mRelativeLayout = relativeLayout;
//mRelativeLayout.setHasTransientState(true);
}
}
}
我的适配器:
public class TrackAdapter extends RecyclerView.Adapter<TrackAdapter.MyViewHolder> {
private List<Track> mTracks;
private Context mContext;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle, mArtist;
public ScrollTextView mScrollTextView;
public MyViewHolder(View view) {
super(view);
mScrollTextView = (ScrollTextView) view.findViewById(R.id.scroll_track);
mArtist = (TextView) view.findViewById(R.id.track_artist);
mTitle = (TextView) view.findViewById(R.id.track_duration);
}
}
public TrackAdapter(List<Track> tracks, Context context) {
mContext = context;
mTracks = tracks;
}
public String getItem(int position) {
return mTracks.get(position).getLocation();
}
@Override
public TrackAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.track_list_layout, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(TrackAdapter.MyViewHolder holder, int position) {
Track track = mTracks.get(position);
holder.mScrollTextView.setTextColor(Color.BLUE);
holder.mScrollTextView.setBackgroundColor(Color.BLACK);
holder.mScrollTextView.setVisibility(View.VISIBLE);
holder.mScrollTextView.setText(track.getTitle());
holder.mArtist.setText(track.getArtist());
//holder.setIsRecyclable(false);
}
@Override
public int getItemCount() {
return mTracks.size();
}
@Override
public long getItemId(int i) {
return i;
}
}
XML RecyclerView:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:showIn="@layout/activity_main"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
XML歌曲项目视图
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<package.name.custom.ScrollTextView
android:id="@+id/scroll_track">
</package.name.custom.ScrollTextView>
<TextView
android:id="@+id/track_artist"
android:layout_below="@id/scroll_track"
/>
<TextView
android:id="@+id/track_duration"
/>
</RelativeLayout>