Android Baseadaper。 getView被调用太少次

时间:2016-12-14 08:52:02

标签: android listview

我在与此问题类似的问题上看过很多帖子,但我仍然无法解决这个问题。我使用自定义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;
}

1 个答案:

答案 0 :(得分:0)

如果其他人遇到类似问题我在这里找到了解决方案:

https://graphics-geek.blogspot.se/2013/02/devbytes-listview-animations.html

像这样设置你的视图:view.setHasTransientState(true)

这似乎可以防止视图在制作动画时被回收。