我的ViewPager有一点UI问题。
我的ViewPager是我的UI的中心。
我有一个包含4个项目的NavigationView和一个包含2个项目的工具栏。
每次单击NavigationView的项目时,我都会更换适配器。因此,我有4个适配器,只有一个导致问题:BrowseAdapter(代码如下)。
此适配器填充了事件列表,并为每个事件提供片段。
值得注意的是,无论eventList的大小如何,ViewPager的setAdapter方法至少需要150ms才能执行,而对于其他适配器,只需要20到50ms即可加载。
我试图在View.post(new Runnable());
方法和AsyncTask<Void, Void, Void>
中对setAdapter进行所有调用:
post方法冻结了用户界面
AsyncTask没有任何改变,因为我只能在UI线程上调用setAdapter(在postExecute方法中),这与没有AsyncTask时调用它基本相同。
我认为这基本上是一个优化问题,但我看不出问题出在哪里。
谢谢你的帮助。
以下是相关代码:
MainActivity:
/*
.
. Import stuff
.
.
.*/
public class MainActivity extends AppCompatActivity implements RequestCallback,
ConnectionCallbacks, OnConnectionFailedListener, FBLoginChanged, LocationListener {
/**
* The main content view
*/
private CustomViewPager mViewPager;
/**
* Adapters : One for each feature of the application
*/
private BrowseAdapter mBrowseAdapter;
private CurrentAdapter mCurrentAdapter = new CurrentAdapter(getFragmentManager());
private CalendarAdapter mCalendarAdapter = new CalendarAdapter(getFragmentManager());
private SettingsAdapter mSettingsAdapter = new SettingsAdapter(getFragmentManager());
/**
* The action bar of the application
*/
private Toolbar mToolbar;
/**
* TabLayout provide the new Material Design tab navigation
*/
private TabLayout mTabLayout;
/**
* Side navigation given by a NavigationView instead of a NavigationDrawer
* to support Material Design
*/
private NavigationView mNavigationView;
private DrawerLayout mDrawerLayout;
/**
* List of all events.
*/
private ArrayList<Event> mEventList = new ArrayList<Event>();
/**
* Provide different way of browsing through the events
*/
private enum BrowseType {
DEFAULT,
POPULAR,
RANDOM
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*.
.
. Initialization stuff
.
.*/
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Closing drawer on item click
mDrawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()){
case R.id.home:
mTabLayout.setVisibility(View.VISIBLE);
mBrowseAdapter.setBrowsingType(BrowseType.DEFAULT);
mViewPager.setAdapter(mBrowseAdapter);
break;
case R.id.favs:
mTabLayout.setVisibility(View.GONE);
mViewPager.setAdapter(mCurrentAdapter);
break;
case R.id.calendar:
mTabLayout.setVisibility(View.GONE);
mViewPager.setAdapter(mCalendarAdapter);
break;
case R.id.setting:
mTabLayout.setVisibility(View.GONE);
mViewPager.setAdapter(mSettingsAdapter);
break;
default:
break;
}
return true;
}
});
mViewPager = (CustomViewPager) findViewById(R.id.pager);
mBrowseAdapter = new BrowseAdapter(this.getFragmentManager(), mEventList);
mTabLayout.setOnTabSelectedListener(new OnTabSelectedListener() {
@Override
// Unused
public void onTabReselected(Tab tab) {
}
@Override
public void onTabSelected(Tab tab) {
switch(tab.getPosition()) {
case 0:
mBrowseAdapter.setBrowsingType(BrowseType.DEFAULT);
break;
case 1:
mBrowseAdapter.setBrowsingType(BrowseType.POPULAR);
break;
default: // Unused
break;
}
mViewPager.setAdapter(mBrowseAdapter);
}
@Override
// Unused
public void onTabUnselected(Tab tab) {
}
});
mViewPager.setAdapter(mBrowseAdapter);
}
}
我的适配器:
private class BrowseAdapter extends FragmentStatePagerAdapter {
private ArrayList<Event> eventList = new ArrayList<Event>();
private BrowseType browseType = BrowseType.DEFAULT;
private HashMap<Integer, EventFragment> fragmentReferenceMap = new HashMap<Integer, EventFragment>();
public BrowseAdapter(FragmentManager fragmentManager,
ArrayList<Event> mEventList) {
super(fragmentManager);
}
public void setBrowsingType(BrowseType type) {
this.browseType = type;
this.commitChanges();
}
public Event getEventById(int id) {
for(Event event : eventList) {
if(event.getId() == id)
return event;
}
return null;
}
public void setJSONData(JSONArray jsonArray) {
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject obj = jsonArray.getJSONObject(i);
Event event = new Event();
event.setId(obj.getInt("id"));
event.setName(obj.getString("name"));
event.setShort_description(obj.getString("short_desc"));
event.setLong_description(obj.getString("long_desc"));
event.setPlace(obj.getString("place").split(";")[0]);
Location loc = new Location("");
loc.setLatitude(Double.valueOf(obj.getString("place")
.split(";")[1]));
loc.setLongitude(Double.valueOf(obj.getString("place")
.split(";")[2]));
event.setLocation(loc);
event.setDate(obj.getString("date"));
eventList.add(event);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
public String getJSONData() {
JSONArray toReturn = new JSONArray();
for (Event event : eventList) {
JSONObject tmp = new JSONObject();
try {
tmp.put("name", event.getName());
tmp.put("short_desc", event.getShort_description());
tmp.put("long_desc", event.getLong_description());
tmp.put("id", event.getId());
tmp.put("date", event.getDate());
tmp.put("place",
event.getPlace()
+ ";"
+ String.valueOf(event.getLocation()
.getLatitude())
+ ";"
+ String.valueOf(event.getLocation()
.getLongitude()));
toReturn.put(tmp);
} catch (JSONException e) {
e.printStackTrace();
}
}
return toReturn.toString();
}
public boolean addItem(Event item) {
return eventList.add(item);
}
@SuppressWarnings("unused")
public Event removeAt(int position) {
return eventList.remove(position);
}
public void commitChanges() {
this.sort();
this.notifyDataSetChanged();
}
private void sort() {
Log.d("SORT", browseType.name());
Collections.sort(eventList, new Comparator<Event>() {
@Override
public int compare(Event arg0, Event arg1) {
float dis1 = arg0.getLocation().distanceTo(
LocationProvidor.getInstance().getLastLocation());
float dis2 = arg1.getLocation().distanceTo(
LocationProvidor.getInstance().getLastLocation());
int userNumber1 = Integer.parseInt(arg0.getUserNumber());
int userNumber2 = Integer.parseInt(arg1.getUserNumber());
switch(browseType) {
case DEFAULT:
return (int) (dis1 - dis2);
case POPULAR:
return userNumber2 - userNumber1;
case RANDOM:
return new Random().nextInt();
default:
return 0;
}
}
});
}
public void empty() {
eventList.clear();
}
@Override
public EventFragment getItem(int position) {
EventFragment frag = EventFragment.newInstance(eventList.get(position));
frag.setIsCurrents(mCurrentAdapter.containsEventId(eventList.get(position).getId()));
fragmentReferenceMap.put(position, frag);
return frag;
}
@Override
public void destroyItem(View container, int position, Object object) {
super.destroyItem(container, position, object);
fragmentReferenceMap.remove(position);
Log.d("fr.blopper.app", "destroy " + position);
}
public EventFragment getFragment(int position) {
return fragmentReferenceMap.get(position);
}
@Override
public int getCount() {
return eventList.size();
}
}
和CustomViewPager(我创建它只是为了测量setAdapter所花费的时间):
import android.content.Context;
import android.util.AttributeSet;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.support.v4.view.PagerAdapter;
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context c) {
super(c);
}
public CustomViewPager(Context c, AttributeSet as) {
super(c, as);
}
@Override
public void setAdapter(PagerAdapter adapter) {
long start = System.currentTimeMillis();
super.setAdapter(adapter);
Log.d("TAG", "Custom time " + (System.currentTimeMillis() - start));
}
}
答案 0 :(得分:1)
找到答案,它与ViewPager无关。
适配器提供的片段正在调用Google API,但答案很慢。