setContentView剖析

博文地址:http://blog.youkuaiyun.com/tanqiantot/article/details/11944539

1、setContentView的作用是将View加载到根view之上,这样当显示view时,先显示根view,然后在显示子view,以此类推,最终将所有view显示出来。


2、setContentView必须要放在findviewbyid之前,因为view在加载之前是无法引用的。

3、setContentView最本质的作用是为要显示的view分配内存。

4、activity、window和view之间的关系:

 而当我们运行程序的时候,有一个setContentView()方法,Activity其实不是显示视图(直观上感觉是它),实际上Activity调用了PhoneWindow的setContentView()方法,然后加载视图,将视图放到这个Window上,而Activity其实构造的时候初始化的是Window(PhoneWindow),Activity其实是个控制单元,即可视的人机交互界面。

打个比喻:

Activity是一个工人,它来控制Window;Window是一面显示屏,用来显示信息;View就是要显示在显示屏上的信息,这些View都是层层重叠在一起(通过infalte()和addView())放到Window显示屏上的。而LayoutInfalter就是用来生成View的一个工具,XML布局文件就是用来生成View的原料

activity调用setContentView其实是调用window的方法
在activity中:
    public void setContentView(int layoutResID) {
        getWindow().setContentView(layoutResID);
        initActionBar();
    }

在PhoneWindow类中:
    @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();
        } else {
            mContentParent.removeAllViews();
        }
        mLayoutInflater.inflate(layoutResID, mContentParent);
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
    }

从上面代码可以看出,最终的根View就是 mContentParent,而mContentParent就是installDecor()生成的DecorView。

5、如何在一个activity中显示不同布局?

1)使用LayoutInflater inflate两个view:v1,v2
2)使用setContentView(View view)方法设置这两个view
具体讲解在http://blog.youkuaiyun.com/yanzi1225627/article/details/7802402
### YOLOv9 Segmentation 中 `AttributeError` 错误分析 在处理 YOLOv9 的分割任务时,如果遇到 `'list' object has no attribute 'shape'` 这样的错误,通常是因为代码试图调用 Python 列表对象上的 `.shape` 属性。然而,`.shape` 是 NumPy 数组或 PyTorch 张量的属性,而不是标准 Python 列表的一部分。 以下是可能的原因以及解决方案: #### 可能原因 1. **数据未正确转换为张量或数组** 如果模型预测的结果是一个列表而非张量,则尝试访问其形状会引发此错误。 2. **中间变量被意外修改成列表** 在某些情况下,程序中的某个部分可能会将原本应该是张量的数据结构替换成了普通的 Python 列表[^1]。 --- ### 解决方案 #### 方法一:检查输入数据类型并强制转换 确保所有涉及的操作都基于正确的数据类型(如 NumPy 或 PyTorch)。可以使用以下方法验证和修正: ```python import torch import numpy as np if isinstance(data, list): # 检测是否为列表 data = torch.tensor(data) if use_torch else np.array(data) # 转换为目标类型 print(data.shape) # 验证 shape 是否可用 ``` 上述代码片段展示了如何检测数据类型,并将其从列表形式转换为支持 `.shape` 属性的对象。 #### 方法二:定位具体发生错误的位置 通过调试工具逐步跟踪代码执行路径,找到触发该异常的具体位置。假设问题发生在如下场景中: ```python predictions = model(image) result_shape = predictions.shape # 此处抛出 AttributeError ``` 此时应确认 `model(image)` 返回的是什么类型的对象。如果是列表,则需进一步调查为何返回值不是预期的张量。 #### 方法三:更新依赖库版本 有时此类问题是由于框架版本不兼容引起的。建议升级至最新稳定版 PyTorch 和 Ultralytics 提供的相关实现: ```bash pip install --upgrade ultralytics pytorch torchvision torchaudio ``` 之后重新运行脚本以测试问题是否得到解决。 --- ### 示例修复代码 下面提供了一个完整的例子用于演示如何避免这种常见陷阱: ```python from ultralytics import YOLO # 加载预训练模型 model = YOLO('yolov9-seg.pt') def process_image(image_path): img = cv2.imread(image_path) # 推理阶段 results = model(img)[0] # 确保结果已转换为适当格式 boxes = results.boxes.xyxy.cpu().numpy() if hasattr(results.boxes, 'xyxy') else [] if not isinstance(boxes, (np.ndarray, torch.Tensor)): raise TypeError("Boxes should be either a tensor or an array.") print(f"Shape of detected bounding boxes: {boxes.shape}") process_image('example.jpg') ``` 在此示例中加入了额外的安全措施来防止潜在类型冲突的发生。 --- ### 总结 当面对 `'list' object has no attribute 'shape'` 类型的错误时,关键是识别哪些地方可能导致了期望之外的数据结构变化,并采取相应手段加以纠正。无论是显式的类型转换还是改进现有逻辑流程都可以有效缓解这一类难题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值