我在与此问题类似的问题上看过很多帖子,但我仍然无法解决这个问题。我使用自定义mediaplayer
和自定义baseadapter
创建简单listfragment
。每个listview
都会保留一个自定义textview
,在按下时会在文本上启动动画(水平滚动)。
getCount()
中的 baseadapter
会正确地返回baseadapter(size == 11)
的大小,但getView()
设置为adapter
后,getView()
只会被调用10次。
目前,我的屏幕包含九个列表项。当我按下顶部项目时,水平滚动开始并播放一首歌曲。如果我然后向上滚动以查看最后一项,该项目也启动了动画,这不是我想要的。
有人遇到过类似的问题,可以帮我解决这个问题吗?
我试图在getView()
中以不同方式更新视图,但仍然会出现动画。对我来说,似乎问题是getCount() - 1
最初只被调用public class ListViewFragment extends ListFragment {
private Context mContext;
private MyBaseAdapter mBaseAdapter;
private MyListViewListener mListViewListener;
private String mJsonStr;
private IPlayer mPlayer;
private int mCurrentTrack = -1;
public interface MyListViewListener {
void getListItemData(String str);
}
public static ListViewFragment newInstance() {
return new ListViewFragment();
}
public ListViewFragment() {
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
mPlayer = new package.name.Player(context);
if(context instanceof MainActivity) {
mListViewListener = (ListViewFragment.MyListViewListener) context;
} else {
throw new ClassCastException(context.toString() + " must implement IEditTextListener");
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_listviewfragment, container, false);
mJsonStr = getArguments().getString("MainActivity");
Gson gson = new Gson();
List<Track> tracks = gson.fromJson(mJsonStr, new TypeToken<List<Track>>(){}.getType());
mBaseAdapter = new MyBaseAdapter(mContext, tracks);
setListAdapter(mBaseAdapter);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
playPauseStop(position);
}
private ScrollTextView mStv;
public void playPauseStop(int position) {
int firstViewItemIndex = getListView().getFirstVisiblePosition();
int viewIndex = position - firstViewItemIndex;
ScrollTextView stv = (ScrollTextView) getListView().getChildAt(viewIndex);
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()) {
// Change track
mPlayer.stop();
mPlayer = new Player(mContext);
String itemData = (String) mBaseAdapter.getItem(position);
mPlayer.startPlayThread(itemData);
mStv.stopScrolling();
mStv.setTextColor(Color.BLUE);
mStv = stv;
stv.startScroll();
stv.setTextColor(Color.RED);
mCurrentTrack = position;
}
if(mCurrentTrack == -1) { // Initial. Start first track.
mStv = stv; // Keep track of view. Needed to stop horizontal scrolling when changing track if view is off screen.
mCurrentTrack = position;
String itemData = (String) mBaseAdapter.getItem(position);
mPlayer.startPlayThread(itemData);
stv.setTextColor(Color.RED);
stv.startScroll();
}
}
}
public class MyBaseAdapter extends BaseAdapter {
private Context mContext;
private Typeface mTypeface;
private List<Track> mTracks;
public MyBaseAdapter(Context context, List<Track> tracks) {
super();
mContext = context;
mTypeface = Typeface.createFromAsset(mContext.getAssets(), "fonts/specialfont.ttf");
mTracks = tracks;
}
@Override
public int getCount() { // Returns the correct size
return mTracks.size();
}
@Override
public Object getItem(int i) {
return mTracks.get(i).getLocation(); // track-URI
}
@Override
public long getItemId(int i) {
return i;
}
private ViewHolder mViewHolder;
static class ViewHolder {
ScrollTextView mTextView;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.layout_list_item, null);
mViewHolder = new ViewHolder();
mViewHolder.mTextView = (ScrollTextView) view.findViewById(R.id.scroll_text);
mViewHolder.mTextView.setTypeface(mTypeface);
mViewHolder.mTextView.setTextColor(Color.BLUE);
mViewHolder.mTextView.setBackgroundColor(Color.BLACK);
mViewHolder.mTextView.setVisibility(View.VISIBLE);
// store the holder with the view.
view.setTag(mViewHolder);
} else { // Avoid calling findViewById() when scrolling
mViewHolder = (ViewHolder) view.getTag();
}
mViewHolder.mTextView.setText(mTracks.get(position).getArtist() + " : " + mTracks.get(position).getName());
return view;
}
}
次。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@android:id/list"
android:layout_height="match_parent"
android:layout_width="match_parent">
</ListView>
</LinearLayout>
layout_listviewfragment.xml
<?xml version="1.0" encoding="utf-8"?>
<package.name.ScrollTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scroll_text"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="72sp">
</package.name.ScrollTextView>
layout_list_item.xml
div[line-number="1"] {
color: red;
}
div[line-number="10"] {
color: green;
}
答案 0 :(得分:0)
如果其他人遇到类似问题我在这里找到了解决方案:
https://graphics-geek.blogspot.se/2013/02/devbytes-listview-animations.html
像这样设置你的视图:view.setHasTransientState(true)
这似乎可以防止视图在制作动画时被回收。