Android知识点<10>Android View - RomoteViews , SurfaceView,RecycleView,ListView

本文介绍了Android中Activity-Window-View的区别,并重点讲解了RemoteViews、RecyclerView和ListView的使用及优化。针对ListView的图片加载错乱问题,提出了解决方案。此外,对比了RecyclerView与ListView在缓存机制和局部刷新上的差异,揭示了RecyclerView在性能优化上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题 : Activity-Window-View三者的差别

Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutInflater像剪刀,Xml配置像窗花图纸。

  1. 在Activity中调用attach,创建了一个Window
  2. 创建的window是其子类PhoneWindow,在attach中创建PhoneWindow
  3. 在Activity中调用setContentView(R.layout.xxx)
  4. 其中实际上是调用的getWindow().setContentView()
  5. 调用PhoneWindow中的setContentView方法
  6. 创建ParentView:
作为ViewGroup的子类,实际是创建的DecorView(作为FramLayout的子类)
  7. 将指定的R.layout.xxx进行填充
通过布局填充器进行填充【其中的parent指的就是DecorView】
  8. 调用到ViewGroup
  9. 调用ViewGroup的removeAllView(),先将所有的view移除掉
  10. 添加新的view:addView()

1.RomoteViews


1.1  Android为了能让进程A显示进程B的View,设计了RmoteView。主要应用于两个场景 : 通知栏通知,桌面小程序

1.2  通知栏

RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.layout_notification);

remoteViews.setTextViewText(R.id.msg, "chapter_5: " + sId);

remoteViews.setImageViewResource(R.id.icon, R.drawable.icon1);

PendingIntent openActivity2PendingIntent = PendingIntent.getActivity(this,0new Intent(this, DemoActivity_2.class),                                                                                                                 PendingIntent.FLAG_UPDATE_CURRENT);

remoteViews.setOnClickPendingIntent(R.id.open_activity2, openActivity2PendingIntent);

1.3  桌面小部件
桌面小部件通过AppWidgetProvider来实现的,它的本质是一个广播。
AppWidgetProvider提供了几个主要的方法, onUpdate, onEnable, onDisable, onDeleted 以及 onReceive。
其中onReceive会根据广播的Action响应, 然后再调用其它方法。
当桌面小部件接收到用户的交互信息,则会通过onReceive传递, 用户通过重写onReceive方法,并判断intent.getAction()是否需要做相应的处理。 如果是更新界面,就需要通过RemoveView实现:

@Override
    public void onReceive(final Context context, Intent intent) {
        super.onReceive(context, intent);
        Log.i(TAG, "onReceive : action = " + intent.getAction());

        // 这里判断是自己的action,做自己的事情,比如小工具被点击了要干啥,这里是做一个动画效果
        if (intent.getAction().equals(CLICK_ACTION)) {
            Toast.makeText(context, "clicked it", Toast.LENGTH_SHORT).show();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    Bitmap srcbBitmap = BitmapFactory.decodeResource(
                            context.getResources(), R.drawable.icon1);
                    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                    for (int i = 0; i < 37; i++) {
                        float degree = (i * 10) % 360;
                        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
                        remoteViews.setImageViewBitmap(R.id.imageView1,rotateBitmap(context, srcbBitmap, degree));
                        Intent intentClick = new Intent();
                        intentClick.setAction(CLICK_ACTION);
                        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0);
                        remoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent);
                        appWidgetManager.updateAppWidget(new ComponentName(context, MyAppWidgetProvider.class),remoteViews);
                        SystemClock.sleep(30);
                    }

                }
            }).start();
        }
    }

1.4 PendingIntent

PendingIntent表示一种处于Pending状态的意图, 即是一种特定,等待,即将发生的意思。

其它进程如果想要在你的app上做一些事情,如果还是传一个Intent,他们是没有执行权限的, 你必须给他们传PendingIntent, 他们才可以执行,因为PendingIntent包含了执行的权限。
上面通知的那段代码, PendingIntent的应用场景,就是给Remoteview设定一个点击的行为,打开DemoActivity_2这个activity。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradient_background"> <!-- 标题栏 --> <RelativeLayout android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?android:attr/actionBarSize" android:background="#44bd32"> <Button android:id="@+id/fanHui" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" android:background="@android:color/transparent" android:foreground="?android:attr/selectableItemBackground" android:text="返回" android:textColor="@android:color/white" android:textSize="16sp" /> </RelativeLayout> <!-- 底部按钮 --> <LinearLayout android:id="@+id/footer_buttons" android:layout_width="match_parent" android:layout_height="1dp" android:layout_alignParentBottom="true" android:background="@android:color/white" android:orientation="horizontal"> <!-- <Button--> <!-- android:id="@+id/device_location"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="match_parent"--> <!-- android:gravity="center"--> <!-- android:text="设备定位"--> <!-- android:textSize="19sp"--> <!-- android:background="#44bd32"--> <!-- android:textColor="@android:color/white" />--> </LinearLayout> <!-- 图片网格容器(添加滚动支持) --> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/footer_buttons" android:layout_below="@id/toolbar" android:background="@android:color/white" android:fillViewport="true" android:padding="0dp"> <GridLayout android:id="@+id/image_grid" android:layout_width="match_parent" android:layout_height="wrap_content" android:columnCount="2" android:padding="0dp" /> </ScrollView> </RelativeLayout> 修改图片网格容器<ScrollView android:layout_width="match_parent" android:layout_height="380dp" android:layout_above="@id/footer_buttons" android:layout_below="@id/toolbar" android:layout_marginBottom="298dp" android:background="@android:color/white" android:fillViewport="true" android:padding="0dp"> </ScrollView>成一个播放视频的模块,其它不变。
最新发布
06-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值