2015-12-27 51 views
2

我的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)); 
} 
} 
+0

在Android Studio中使用方法跟踪来确定您在哪里花费时间。 – CommonsWare

+0

@CommonsWare不幸的是,我没有使用Android Studio(我的电脑速度太慢),我使用Gradle构建,但是我使用Atom编辑器编写。 – Peyphour

回答

1

找到了答案,它无关的ViewPager。

适配器提供的碎片正在对Google API进行调用,该API很慢回答。

相关问题