我的ViewPager有一點UI問題。ViewPager.setAdapter需要200ms到300ms才能執行
我的ViewPager是我的用戶界面的中心。
我有一個NavigationView 4個項目和一個工具欄2項。
每次點擊NavigationView的項目時,我都會替換適配器。因此,我有4個適配器,只有一個導致問題:BrowseAdapter(代碼如下)。
該適配器充滿事件列表併爲每個事件提供一個片段。
需要知道的是,無論eventList的大小如何,ViewPager的setAdapter方法至少需要150ms才能執行,而對於其他適配器,只需要20-50ms的加載。
我曾試圖把所有調用setAdapter在View.post(new Runnable());
方法,並在:
POST方法凍結了UI
的的AsyncTask什麼都沒有改變,因爲我只能叫setAdapter在UI線程上(在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採取E):
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));
}
}
在Android Studio中使用方法跟蹤來確定您在哪裏花費時間。 – CommonsWare
@CommonsWare不幸的是,我沒有使用Android Studio(我的電腦速度太慢),我使用Gradle構建,但是我使用Atom編輯器編寫。 – Peyphour