【问题标题】:Android: Repeat a complex view inside a LinearLayout (Performance)Android:在 LinearLayout 中重复复杂视图(性能)
【发布时间】:2018-02-07 17:43:52
【问题描述】:

我正在尝试创建一个需要在复杂布局中显示 VideoView 列表的应用程序。这个概念与 Instagram 和 Facebook 应用程序非常相似。带有大量视频和其他内容的主屏幕。

我创建了一个由工具栏组成的视图,其中包含三个项目,工具栏下的 videoView 和 videoview 下的 bottomBar 以及一些 textviews 和 imageviews。

我在一个简单的垂直线性布局中动态地膨胀这个视图。为了尽可能减少处理器的压力,我一次创建十个视图。一旦我到达滚动条的末尾,我再添加 15 个,依此类推。 当然我不会初始化任何视频,我只是使用 inScale、inSampleSize 和 inDensity 参数专门调整大小的位图设置 videoView 背景。 这个概念与 Instagram 相同。当我的观看次数达到 40 或 50 次时,问题就出现了。它开始滞后非常糟糕。

这就是我膨胀布局的方式:

View videoView = getLayoutInflater().inflate(R.layout.post_layout_2, null);

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT
    );
    params.setMargins(0, 25, 0, 0);
    videoView.setLayoutParams(params);

    //Initialize components
    CircleImageView profImg = (CircleImageView) videoView.findViewById(R.id.post_profile_image);
    TextView postUsername = (TextView) videoView.findViewById(R.id.post_username);
    TextView postChallengeTitile = (TextView) videoView.findViewById(R.id.post_challenge_title);
    TextView postViews = (TextView) videoView.findViewById(R.id.post_views_count);
    TextView postLikes = (TextView) videoView.findViewById(R.id.post_like_count);

    //Fill components
    profImg.setImageBitmap(imgProfile);
    postUsername.setText("@"+username);
    postChallengeTitile.setText("#"+ challengeTitle);
    postViews.setText(String.valueOf(NumberFormat.getNumberInstance(Locale.US).format(views)));
    postLikes.setText(String.valueOf(NumberFormat.getNumberInstance(Locale.US).format(count)));
    cont.addView(videoView);


    final TextView durationTxt = (TextView) videoView.findViewById(R.id.video_duration_txt);
    final VideoView video = (VideoView) videoView.findViewById(R.id.videoView2);
    final ProgressBar progressDialog = (ProgressBar) videoView.findViewById(R.id.progressBar);
    //final String pathVideo = "android.resource://" +  getActivity().getPackageName() + "/" +  R.raw.mot;
    final String pathVideo = "https://videoLink";
    final Uri uri  = Uri.parse(pathVideo);


    BitmapFactory.Options myBit = new BitmapFactory.Options();
    myBit.inSampleSize = calculateInSampleSize(myBit, 300, 350);
    myBit.inScaled = true;
    myBit.inDensity = 600;
    myBit.inTargetDensity = 300* myBit.inSampleSize;
    Bitmap resize = BitmapFactory.decodeResource(getResources(), R.drawable.foto_test, myBit);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        video.setBackground(new BitmapDrawable(getResources(), resize));
    }

我想知道 Instagram 是如何加载这么多视频而没有延迟的?我可以使用一些技巧吗?

【问题讨论】:

  • 您想显示一个列表,但您使用 LinearLayout 作为列表项的 ViewGroup(= VideoViews)?那么你肯定需要使用带有 LinearLayoutManager() 的 RecyclerView。它的性能会好很多,因为它重用了 Views,所以它只需要可以同时显示的数量加上两个或三个用于滚动

标签: android performance android-layout


【解决方案1】:

这是RecyclerView 的经典用例。如果会膨胀足够多的视图以填满屏幕,那么当您向下滚动时将重用创建的视图。

另一个选项是来自 Facebook 的Litho。这是来自 Facebook 的 article,关于他们是如何做到的。

【讨论】:

  • 使用 RecyclerView 我可以用不同的数据填充视图吗?例如不同的视频或用户名或图像配置文件等等?
  • @AlessioTrecani 当然可以。通常数据是List 或项目数组。 Link 给指南。您甚至可以拥有多种项目类型。
猜你喜欢
  • 1970-01-01
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多