【问题标题】:List View inside ViewPager using nested fragments - huge performance drop使用嵌套片段在 ViewPager 中列出视图 - 性能大幅下降
【发布时间】:2018-03-21 19:24:37
【问题描述】:

在主题中,我对活动的优化有很大的问题。 wireframe

在根级别,我们有三个控件: - 选项卡布局,与 ViewPager 相关 - SurfaceView 显示每个片段的情节 - 和 ViewPager 本身

ViewPager 显示在图片上标记为红色的片段。每个片段都包含子片段(绿色边框),显示元素列表以及一些负责编辑的控件。元素显示在带有自定义适配器的 ListView 中。我对这种观点有两个问题。

第一个问题: 我正在使用 FragmenStatePagerAdapter 来显示视图。我将已创建片段的实例存储在适配器 Map 中,以重用它们。

protected Map<Integer, Fragment> fragmentReferenceMap = new HashMap<Integer, Fragment>();
        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            if(!fragmentReferenceMap.containsKey(position)) {
                econetFragmentReferenceMap.put(position, MyFragment.newInstance(position));
            }
            return fragmentReferenceMap.get(position);
        }

当我滑回创建的 Fragment 适配器时,会从地图返回创建的实例,但即便如此,我的 Fragment 上的 onCreate() 也会被调用并再次创建整个 Fragment。我知道 ViewPager 有设置离屏限制的选项,但是没有办法重用这个片段视图吗?

第二个问题是膨胀 ListView 的整个过程需要很长时间。我尝试更改 offScreenLimit,但是当它设置为 7(最大查看页面数)时,应用程序会在显示活动前冻结几秒钟,并且我看到滑动动画有滞后。当我将其设置为 1 或 0 等其他数字时,活动创建速度更快,但在滑动时会丢失很多帧。我使用的所有片段数据都存储在单个数据表中。这种方法很容易存储所有更改,即使其中一个片段被 ViewPager 破坏,所以我想坚持下去。我尝试为适配器模拟数据,我发现它对它的创建时间没有太大影响。我也厌倦了使用异步任务 getView 方法来收集单行的整个数据,并在 onPostExecute 方法中将其添加到视图中,但它没有给出令人满意的结果

这是我的 getView 方法:

@NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        convertView = super.getView(position,convertView,parent);

        Spinner spinner = (Spinner) convertView.findViewById(R.id.UserMode);

        final TextView startTime = (TextView) convertView.findViewById(R.id.rangeStart);
        final TextView stopTime = (TextView) convertView.findViewById(R.id.rangeStop);

        if(getConverter() != null){

            List<String> values = getConverter().getValuesLabels();
            ArrayAdapter spinerAdapter = new ArrayAdapter(context, R.layout.custom_sec_spinner, R.id.tvSpinnerText, values);
            spinerAdapter.setDropDownViewResource(R.layout.spinner_dodatkowe_wiersz);
            spinner.setAdapter(spinerAdapter);

            spinner.setSelection(getConverter().getUserMode(modeIndex, position));

            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                    getConverter().setUserMode(modeIndex, position, position) ;
                }

                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {

                }
            });

            int[] start = getConverter().getRangeStart(modeIndex, position);
            int[] end = getConverter().getRangeEnd(modeIndex, position);

            startTime.setText(start[0] + ":" + start[1]);
            stopTime.setText(end[0] + ":" + end[1]);

            startTime.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    TimePickerDialog mTimePicker;

                    int[] selectedTime = getConverter().getRangeStart(modeIndex, position);

                    mTimePicker = new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
                        @Override
                        public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
                            getConverter().setRangeStart(modeIndex, position, new int[]{selectedHour, selectedMinute});
                            startTime.setText(selectedHour + ":" + selectedMinute);
                        }
                    }, selectedTime[0], selectedTime[1], true);
                    mTimePicker.show();
                }
            });

            stopTime.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    TimePickerDialog mTimePicker;

                    int[] selectedTime = getConverter().getRangeEnd(modeIndex, position);

                    mTimePicker = new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
                        @Override
                        public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
                            getConverter().setRangeEnd(modeIndex, position, new int[]{selectedHour, selectedMinute});
                            stopTime.setText(selectedHour + ":" + selectedMinute);
                        }
                    }, selectedTime[0], selectedTime[1], true);
                    mTimePicker.show();
                }
            });
        }
        else{
            spinner.setEnabled(false);
        }

        return convertView;
    }

那么,您能否告诉我如何优化我的适配器和 ListView 以使其更快地工作,或者为用户提供没有任何滞后的体验?我将不胜感激任何建议甚至类似文章的链接,因为我一直在寻找一整天并尝试了几乎所有东西。谢谢你:)

【问题讨论】:

    标签: android listview android-viewpager android-nested-fragment


    【解决方案1】:
    1. 在后台线程上创建列表视图。
      使用后台线程(“工作线程”)消除了主线程的压力,因此它可以专注于绘制 UI。在许多情况下,使用 AsyncTask 提供了一种在主线程之外执行工作的简单方法。 AsyncTask 自动将所有的 execute() 请求排队并按顺序执行。这种行为对于特定进程是全局的,意味着您无需担心创建自己的线程池。 reference link
    2. 尝试使用 Holder Class 来提高性能
      ViewHolder 对象将每个组件视图存储在 Layout 的 tag 字段中,因此您可以立即访问它们而无需重复查找它们。首先,您需要创建一个类来保存您的确切视图集。

      View row=view;
      
      Holder holder=null;
      if(row==null){
          LayoutInflater inflater= (LayoutInflater)mContext.getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
          row= inflater.inflate(R.layout.half_movie,viewGroup,false);
          holder=new Holder(row);
          row.setTag(holder);
      }else{
      
      
          holder= (Holder) row.getTag();
      
      
      
      }
      

    【讨论】:

    • 其实我已经有了viewHolder,但是整个机制隐藏在基类中,你看不到。
    • 我已经尝试过 AsyncTask,但我想问题是我的 onPostExecute 任务在滑动动画期间被调用,并且会在瞬间冻结 gui。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多