0

I have a hierarchical app where the root activity has a ListView which loads an activity based on which item is clicked. That activity in turn loads an activity based on a ListView selection and so on.

My transitions are pretty fast and Activity B loads as soon as its transition animation is over. The slowest part is beginning the transition to the next activity.

I click an item and it's half a second before the transition animation begins. What is causing this delay? The same delay exists when using onBackPressed to go to a parent activity (single_instance_top, not a new instance or recreated). Is this a delay built in so that the user can see any visual effects of their selection before the next screen loads?

Here is one of my Activities. The onItemClick method is called from my ListView adapter, whose onClick method doesn't do anything but call the method seen. Any suggestions?

public class Activity_Course extends ActionBarActivity {

    static final String COURSE_ID = "my.COURSE_ID";
    public int courseId;

    public static boolean needsRefresh = false;
    public static boolean isRecreated = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
        setContentView(R.layout.activity_course);


        if (savedInstanceState == null) {
            Handler h = new Handler();
            h.post(new Runnable(){
                public void run(){
                    // do your heave tasks
                    Intent intent = getIntent();
                    courseId = intent.getIntExtra(MainFragment.COURSE_ID, 0);
                    getSupportFragmentManager().beginTransaction()
                    .add(R.id.course_activity_frame, new CourseActivityFragment()).commit();
                }
            });
        } else {
            courseId = savedInstanceState.getInt(COURSE_ID);
            Activity_Course.isRecreated = true;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.course, menu);
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {                   
             menu.findItem(R.id.menu_overflow).setIcon(R.drawable.ic_menu_moreoverflow_normal_holo_light);
         }
        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();
        if (id == R.id.edit_course_menu_item) {
            Intent i = new Intent(this, Activity_EditCourse.class);
            i.putExtra(COURSE_ID, courseId);
            startActivity(i);
        } else if(id == R.id.edit_course_gpa_menu_item){
            Intent i = new Intent(this, Activity_EditCourseGPA.class);
            i.putExtra(COURSE_ID, courseId);
            startActivity(i);
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class CourseActivityFragment extends Fragment {

        public final static String GRADE_ID = "my.GRADE_ID";
        public final static String CAT_ID = "my.CAT_ID";
        public final static String COURSE_ID = "my.COURSE_ID";
        public final static String CAT_STRING = "my.CAT_STRING";
        public final static String COURSE_STRING = "my.COURSE_STRING";
        public final static String SEMESTER_STRING = "my.SEMESTER_STRING";

        View rootView;
        int courseId;
        DBAdapter db;
        ScaledGradeHolder gholder;
        ProgressBar pbar;
        ListView categoryListView;
        TextView percentAvg_tv;
        TextView gpa_tv;
        TextView letterGrade_tv;
        Activity curActivity;
        CourseActivityFragment curFrag;
        int gradeColor;
        Course course;
        Adapter_CategoryList catAdapter;
        public final static String CATEGORY_ID = "my.CATEGORY_ID";

        public ArrayList<Category> catList = new ArrayList<Category>();

        public CourseActivityFragment() {
        }

        @Override
        public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setRetainInstance(true);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            rootView = inflater.inflate(R.layout.fragment_course,
                    container, false);

            db = new DBAdapter(this.getActivity());
            curActivity = this.getActivity();
            curFrag = this;

            if (savedInstanceState != null) {
                courseId = savedInstanceState.getInt(COURSE_ID);

                if(catAdapter != null){
                    catAdapter.clear();
                    catList.clear();
                }

            } else {
                courseId = ((Activity_Course) this.getActivity()).courseId;
            }


            if(Activity_Course.isRecreated){
                if(catAdapter != null)
                    catAdapter.clear();
                Activity_Course.isRecreated = false;
            }


            db.open();
            course = db.getCourse(courseId);
            gholder = db.getScaledCourseGradeHolder(courseId);
            db.close();

            setViews();

            setListData();

            Resources res = getResources();
            categoryListView = (ListView) rootView.findViewById(R.id.cat_list_view);

//                  Applies the adapter to populate the ListView
            catAdapter = new Adapter_CategoryList(curActivity, catList, res, curFrag);
            categoryListView.setAdapter(catAdapter);
            pbar.setVisibility(View.GONE);







            return rootView;
        }

        public void setListData()
        {
            db.open();
            Category[] gt = db.getCategoriesInCourse(courseId);
            db.close();
            if(gt!=null){
                for(int i = 0; i < gt.length; i++) {
                    catList.add(gt[i]);
                }
            }
        }

        public void setViews(){
            // Set header info
            pbar = (ProgressBar)rootView.findViewById(R.id.progressBar1);
            TextView header = (TextView)rootView.findViewById(R.id.course_header);
            header.setText(course.getTitle());
            ((TextView) rootView.findViewById(R.id.semester_header)).setText(course.getSemesterString());

            setGradeSummaryViews();

//          Set column headers of the gradeType ListView
            LinearLayout catHeader = (LinearLayout) rootView.findViewById(R.id.linLayCatheader);
            TextView tv = (TextView)catHeader.findViewById(R.id.category_column);
            TextView tv2 = (TextView)catHeader.findViewById(R.id.weight_column);
            TextView tv3 = (TextView)catHeader.findViewById(R.id.gradecount_column);
            TextView tv4 = (TextView)catHeader.findViewById(R.id.percentage_column);
            tv.setText(R.string.cat_header);
            tv2.setText(R.string.weight_header);
            tv3.setText(R.string.count_header);
            tv4.setText(R.string.percent_header);
        }

        public void setGradeSummaryViews(){
            db.open();
            gholder = db.getScaledCourseGradeHolder(courseId);
            this.getActivity().setTitle(db.getCourse(courseId).getTitle());
            db.close();

            gradeColor = gholder.getColorId();

            // Set gpa
            gpa_tv = (TextView) rootView.findViewById(R.id.gpaGradeTextView);
            gpa_tv.setText(gholder.getGpaGradeString());
            gpa_tv.setTextColor(gradeColor);

            // Set percent average
            percentAvg_tv = (TextView) rootView.findViewById(R.id.percentTextView);
            percentAvg_tv.setText(gholder.getNumberGradeStringPercent());
            percentAvg_tv.setTextColor(gradeColor);

            // Set letter grade
            letterGrade_tv = (TextView) rootView.findViewById(R.id.letterGradeTextView);
            letterGrade_tv.setText(gholder.getLetterGrade());
            letterGrade_tv.setTextColor(gradeColor);
        }

         public void onItemClick(int position){

                Intent i = new Intent(this.getActivity(), Activity_Category.class);
                i.putExtra(CATEGORY_ID, catAdapter.getItem(position).getCategoryId());
                i.putExtra(MainFragment.COURSE_ID, courseId);
                Activity_Category.catId = catAdapter.getItem(position).getCategoryId();
                startActivity(i);


          }

         @Override
            public void onResume(){
                super.onResume();
                if(categoryListView == null)
                    return;
                int cnt = categoryListView.getChildCount();
                for(int i = 0; i < cnt; i++){
                    categoryListView.getChildAt(i).setBackgroundColor(0x00000000);
                }
                //coursesListView.setAdapter(courseAdapter);
            }

         @Override
         public void onStart(){
             super.onStart();
             if(Activity_Course.needsRefresh){
                    catList.clear();
                    setListData();
                    catAdapter.notifyDataSetChanged();
                    setGradeSummaryViews();
                    Activity_Course.needsRefresh = false;
              }
         }

         @Override
            public void onSaveInstanceState(Bundle outState){
                super.onSaveInstanceState(outState);
                outState.putInt(COURSE_ID, courseId);
            }

    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState){
        // Save current CourseId
        savedInstanceState.putInt(COURSE_ID, courseId);

        // Call superclass to save view hierarchy state
        super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
    }

    @Override
    public boolean onNavigateUp() { 
        boolean x = super.onSupportNavigateUp();
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
        return x;
    }

}
NSouth
  • 5,067
  • 7
  • 48
  • 83
  • did you try a trace view and see where the time goes ?? – Panther Oct 28 '14 at 13:37
  • I haven't used that feature yet... how is it used? – NSouth Oct 28 '14 at 13:38
  • you should learn to use the `timeline` in `traceview`. However as for the beginning, you can consider log time at the start and end of the method where you consider it takes time and see which method actually consumes more time – Panther Oct 28 '14 at 13:40
  • Cool, I measured between an item onClick and the completion of the next Activity's view. Would you mind taking a look? My thoughts are: A) Most of the time seems to be from android os and support callbacks, nothing I can do about them. B) Most methods are related to the activity being loaded (Activity_Course), so why do I feel the delay before the transition begins to that activity? http://i.imgur.com/LdKZJMg.png – NSouth Oct 28 '14 at 14:30

1 Answers1

1

You can change the "default" transition between activities and use some transition that is very fast. See : example

Also you can do less things in onCreate and onResume so the loading time will be very short and start loading and filling of the data after a short delay ( 50 - 100 ms) with handler.

Community
  • 1
  • 1
danysz
  • 580
  • 3
  • 11