我在MainActivity中创建了一个包含5个标签的ViewPager。在第一个选项卡中,我放置了一个ListView以显示一些项目。问题是每当我滑动到另一个标签然后返回到第一个标签时,列表中的项目都是重复的(即列表包含A-B-C,然后是A-B-C-A-B-C)。奇怪的是,只有当我比第二个选项卡滑动时才会发生这种情况。这是我的代码:
MainActivity:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
//private String[] tabs = { "Mixed", "Videos", "Audio", "Text", "Picture" };
final int[] ICONS = new int[] {
R.drawable.mixed,
R.drawable.video,
R.drawable.audio,
R.drawable.note,
R.drawable.photo
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (int i=0;i<ICONS.length;i++) {
actionBar.addTab(actionBar.newTab().setIcon(MainActivity.this.getResources().getDrawable(ICONS[i]))
.setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public android.support.v4.app.Fragment getItem(int index) {
switch (index) {
case 0:
return MixedFragment.newInstance();
case 1:
return new VideosFragment();
case 2:
return new AudioFragment();
case 3:
return new TextFragment();
case 4:
return new PictureFragment();
}
return null;
}
@Override
public int getCount() {
// get item count - equal to number of tabs
return 5;
}
}
}
片段类:
public class MixedFragment extends ListFragment implements AdapterView.OnItemClickListener {
ListView mixed;
JSONArray videos =null;
List<NameValuePair> row;
ArrayAdapter<VideoRow> adapter;
private List<VideoRow> listRow = new ArrayList<>();
private List<String> pathList = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.mixed, container, false);
mixed = (ListView) v.findViewById(android.R.id.list);
row = new ArrayList<>();
// mixed.setOnItemClickListener(this);
new populateLists().execute();
return v;
}
public static MixedFragment newInstance(){
MixedFragment mx = new MixedFragment();
return mx;
}
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
String sendPath = pathList.get(position);
Intent start = new Intent(getActivity(), PlayVideo.class);
start.putExtra("Path", sendPath);
startActivity(start);
}
class populateLists extends AsyncTask<String,String,String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
JSONParser jParser = new JSONParser();
JSONObject obj = jParser.makeHttpRequest(Config.URL_Populate,"GET",row);
try {
// Checking for SUCCESS TAG
int success = obj.getInt("success");
if (success == 1) {
// videos found
// Getting Array of videos
videos = obj.getJSONArray("video");
// looping through All videos
for (int i = 0; i < videos.length(); i++) {
JSONObject c = videos.getJSONObject(i);
// Storing each json item in variable
String path = Config.URL_2server+c.getString("path");
String thumbnail = c.getString("thumbnail");
String title = c.getString("title");
String name =c.getString("name");
title = "\""+title+"\"";
byte[] bytes = Base64.decode(thumbnail,Base64.DEFAULT);
Bitmap thumb = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
pathList.add(path);
listRow.add(new VideoRow(path,thumb, name, title));
}
}
adapter = new MyListAdapterFrag(getActivity(), R.layout.enlarged_list_row, listRow,1);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
mixed.setAdapter(adapter);
}
}
}
ListAdapter:
public class MyListAdapterFrag extends ArrayAdapter<VideoRow> {
List<VideoRow> lRow;
Bitmap myThumb;
int activity;
public MyListAdapterFrag(Context context, int resource, List<VideoRow> listRow, int i) {
super(context, resource, listRow);
lRow=listRow;
activity=i;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
View row = convertView;
if (row == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
if (activity == 1) {
row = inflater.inflate(R.layout.list_row, parent, false);
} else if (activity == 2) {
row = inflater.inflate(R.layout.enlarged_list_row, parent, false);
}
viewHolder = new ViewHolder();
viewHolder.txtName = (TextView) row.findViewById(R.id.name);
viewHolder.txtTitle = (TextView) row.findViewById(R.id.title);
viewHolder.imageThumb = (ImageView) row.findViewById(R.id.thumbnail);
row.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) row.getTag();
}
VideoRow thisRow = lRow.get(position);
viewHolder.txtName.setText(thisRow.getName());
Bitmap thumb = thisRow.getThumb();
if (activity == 1) {
myThumb = Bitmap.createScaledBitmap(thumb, 40, 40, true);
} else if (activity == 2) {
myThumb = Bitmap.createScaledBitmap(thumb, 60, 60, true);
}
viewHolder.imageThumb.setImageBitmap(myThumb);
viewHolder.txtTitle.setText(thisRow.getTitle());
return row;
}
private static class ViewHolder {
ImageView imageThumb;
TextView txtTitle;
TextView txtName;
}
}
那么,你们有什么想法导致这个错误的原因吗?
答案 0 :(得分:4)
当您移动到ViewPager中的另一个片段时,前一个片段的视图可能会被破坏(我认为默认大小是两个片段,例如片段#2到达屏幕时,片段#0被破坏)。当你回去时,它被重新创建。每次返回MixedFragment
时,都会调用其onCreateView
方法,但在销毁时,您永远不会清除适配器。这就是你看到重复的原因。
因此,您可以在视图被销毁时清除适配器:
@Override
public void onDestroyView() {
super.onDestroyView();
adapter.clear();
}
答案 1 :(得分:4)
问题是由于当ViewPager超过某个点时你的片段被重新初始化了。
这意味着,一旦你的第一个片段超过限制,当你返回它时,将再次调用onCreateView函数。您需要检查populateLists
AsyncTask是否确实需要触发。
或者,您可以增加屏幕外页面限制,以保留所有碎片。