从现有视图创建新视图

发布于 2024-12-21 00:47:50 字数 3312 浏览 0 评论 0原文

我一直在开发一个在列表活动中显示提要的应用程序。 首先,我获取信息并解析它,然后将其放入我创建的“FeedType”数组中,该数组有 3 个字段:位图图片、字符串名称和查看内容。 内容代表提要的内容,并且有不同类型的内容。 该数组在解析过程中被初始化。

我在 xml 文件中创建了 feed 布局。 使用 addView() 创建了包含“内容”的 ImageView、TextView 和 LinearLayout。 我创建了一个包装器并创建了 ListAdapter 以重用列表中的对象。

当我尝试使用添加一个已经是其他 LinearLayout 子级的视图时,我的问题就开始了,它的发生是因为当我从数组中检索内容时,我将取消对现有视图的引用,而不是新视图。

有没有办法从现有视图创建新视图?或者有人有其他解决方案?

代码:

public class FeedType {

    private Bitmap profilePicSrc;
    private String name;
    private View feedContent;
    private Context context;
    private final String PIC_BASE_SRC = "xxx";
    private final String PIC_END_SRC = "xxx";


    public FeedType(String contactId, String name, View feedContent, Context context){
        try {
            this.profilePicSrc = BitmapFactory.decodeStream((InputStream)new URL(PIC_BASE_SRC + contactId.toString() + PIC_END_SRC).getContent());
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.name = name;
        this.context = context;
        this.feedContent = feedContent;
    }

    public String getName(){
        return name;
    }

    public Bitmap getProfilePicture(){
        return profilePicSrc;
    }

    public View getContent(){
        return this.feedContent;
    }
}

包装类:

public class FeedWrapper {

    private View base;
    private ImageView pic = null;
    private TextView name = null;
    private LinearLayout content = null;

    public FeedWrapper(View base) {
        this.base = base;
    }

    public ImageView getProfilePicture() {
        if (pic == null) {
            pic = (ImageView)base.findViewById(R.id.pic);
        }
        return(pic);
    }

    public TextView getName() {
        if (name == null) {
            name = (TextView)base.findViewById(R.id.name);
        }
        return(name);
    }

    public LinearLayout getContent() {
        if (content == null) {
            content = (LinearLayout)base.findViewById(R.id.content);
        }
        else content.removeAllViews();
        return(content);
    }

}

ListAdapter 类:

private class FeedListAdapter extends ArrayAdapter<Object> {

        public FeedListAdapter() {
            super(Feeds.this, R.layout.feed, new Object[feedArrLength]);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View feed = convertView;
            FeedWrapper wrapper = null;

            if (feed == null) {

                feed = getLayoutInflater().inflate(R.layout.feed, parent, false);
                wrapper = new FeedWrapper(feed);
                feed.setTag(wrapper);
            }
            else {
                wrapper = (FeedWrapper)feed.getTag();
            }

            wrapper.getName().setText(arr.get(position).getName());
            wrapper.getProfilePicture().setImageBitmap(arr.get(position).getProfilePicture());
            wrapper.getContent().addView(arr.get(position).getContent());
            return(feed);
        }
    }

我知道这有点难以理解,如果您有疑问请询问。

预先感谢,埃拉德!

I've been working on an app that displays feeds in a list activity.
At first, I'm getting the information and parsing it, and I put it in a array of "FeedType" that I've created, that has 3 fields: Bitmap pic, String name and View content.
The content represent the feed's content, and there's different type of contents.
This array is being initialized in the parsing process.

I created the feed layout in a xml file.
Created a ImageView, TextView and LinearLayout that will contain the "content" by using addView().
I've created a wrapper and create my ListAdapter to reuse the object in the list.

My problem start when I'm trying to use add a view who is already a child of other LinearLayout, and it's happening because when I retrieve the content from the array I'm retireving the reference to the existing view, and not a new view.

Is there a way to create a new view from existing view? Or somebody got other solution?

Code:

public class FeedType {

    private Bitmap profilePicSrc;
    private String name;
    private View feedContent;
    private Context context;
    private final String PIC_BASE_SRC = "xxx";
    private final String PIC_END_SRC = "xxx";


    public FeedType(String contactId, String name, View feedContent, Context context){
        try {
            this.profilePicSrc = BitmapFactory.decodeStream((InputStream)new URL(PIC_BASE_SRC + contactId.toString() + PIC_END_SRC).getContent());
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.name = name;
        this.context = context;
        this.feedContent = feedContent;
    }

    public String getName(){
        return name;
    }

    public Bitmap getProfilePicture(){
        return profilePicSrc;
    }

    public View getContent(){
        return this.feedContent;
    }
}

Wrapper class:

public class FeedWrapper {

    private View base;
    private ImageView pic = null;
    private TextView name = null;
    private LinearLayout content = null;

    public FeedWrapper(View base) {
        this.base = base;
    }

    public ImageView getProfilePicture() {
        if (pic == null) {
            pic = (ImageView)base.findViewById(R.id.pic);
        }
        return(pic);
    }

    public TextView getName() {
        if (name == null) {
            name = (TextView)base.findViewById(R.id.name);
        }
        return(name);
    }

    public LinearLayout getContent() {
        if (content == null) {
            content = (LinearLayout)base.findViewById(R.id.content);
        }
        else content.removeAllViews();
        return(content);
    }

}

ListAdapter class:

private class FeedListAdapter extends ArrayAdapter<Object> {

        public FeedListAdapter() {
            super(Feeds.this, R.layout.feed, new Object[feedArrLength]);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View feed = convertView;
            FeedWrapper wrapper = null;

            if (feed == null) {

                feed = getLayoutInflater().inflate(R.layout.feed, parent, false);
                wrapper = new FeedWrapper(feed);
                feed.setTag(wrapper);
            }
            else {
                wrapper = (FeedWrapper)feed.getTag();
            }

            wrapper.getName().setText(arr.get(position).getName());
            wrapper.getProfilePicture().setImageBitmap(arr.get(position).getProfilePicture());
            wrapper.getContent().addView(arr.get(position).getContent());
            return(feed);
        }
    }

I know that's a bit difficult to understand, if you have questions please ask.

Thanks in advance, Elad!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚雾 2024-12-28 00:47:50

我认为将 View 保留在 FeedType 对象中是错误的方法。仅保留 FeedType 中的数据。

例如,创建新类 FeedContent,其中包含有关 Feed 内容的解析数据(不是任何视图):

class FeedContent {

... // i.e. private List<String> contents;

}

然后更改您的 FeedType 类:

public class FeedType {

private Bitmap profilePicSrc;
private String name;
private FeedContent feedContent;
private Context context;
private final String PIC_BASE_SRC = "xxx";
private final String PIC_END_SRC = "xxx";


public FeedType(String contactId, String name, FeedContent feedContent, Context context){
    try {
        this.profilePicSrc = BitmapFactory.decodeStream((InputStream)new URL(PIC_BASE_SRC + contactId.toString() + PIC_END_SRC).getContent());
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    this.name = name;
    this.context = context;
    this.feedContent = feedContent;
}

public String getName(){
    return name;
}

public Bitmap getProfilePicture(){
    return profilePicSrc;
}

public FeedContent getContent(){
    return this.feedContent;
}

}

然后创建您的 FeedListAdapter喜欢:

private class FeedListAdapter extends ArrayAdapter<Object> {

    public FeedListAdapter() {
        super(Feeds.this, R.layout.feed, new Object[feedArrLength]);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View feed = convertView;
        FeedWrapper wrapper = null;

        if (feed == null) {

            feed = getLayoutInflater().inflate(R.layout.feed, parent, false);
            wrapper = new FeedWrapper(feed);
            feed.setTag(wrapper);
        }
        else {
            wrapper = (FeedWrapper)feed.getTag();
        }

        wrapper.getName().setText(arr.get(position).getName());
        wrapper.getProfilePicture().setImageBitmap(arr.get(position).getProfilePicture());
        View feedContentView = createContentView(arr.get(position).getContent());
        wrapper.getContent().addView(feedContentView);
        return(feed);
    }

    private View createContentView(FeedContent feedContent) {
        ... // Here you shuold inflate new view and fill it with data from "feedContent"
    }
}

I think it's a wrong way to keep View in FeedType object. Keep only data in FeedType.

For example create new class FeedContent which contains parsed data about feed content (not any views):

class FeedContent {

... // i.e. private List<String> contents;

}

Then change your FeedType class:

public class FeedType {

private Bitmap profilePicSrc;
private String name;
private FeedContent feedContent;
private Context context;
private final String PIC_BASE_SRC = "xxx";
private final String PIC_END_SRC = "xxx";


public FeedType(String contactId, String name, FeedContent feedContent, Context context){
    try {
        this.profilePicSrc = BitmapFactory.decodeStream((InputStream)new URL(PIC_BASE_SRC + contactId.toString() + PIC_END_SRC).getContent());
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    this.name = name;
    this.context = context;
    this.feedContent = feedContent;
}

public String getName(){
    return name;
}

public Bitmap getProfilePicture(){
    return profilePicSrc;
}

public FeedContent getContent(){
    return this.feedContent;
}

}

And then make your FeedListAdapter like:

private class FeedListAdapter extends ArrayAdapter<Object> {

    public FeedListAdapter() {
        super(Feeds.this, R.layout.feed, new Object[feedArrLength]);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View feed = convertView;
        FeedWrapper wrapper = null;

        if (feed == null) {

            feed = getLayoutInflater().inflate(R.layout.feed, parent, false);
            wrapper = new FeedWrapper(feed);
            feed.setTag(wrapper);
        }
        else {
            wrapper = (FeedWrapper)feed.getTag();
        }

        wrapper.getName().setText(arr.get(position).getName());
        wrapper.getProfilePicture().setImageBitmap(arr.get(position).getProfilePicture());
        View feedContentView = createContentView(arr.get(position).getContent());
        wrapper.getContent().addView(feedContentView);
        return(feed);
    }

    private View createContentView(FeedContent feedContent) {
        ... // Here you shuold inflate new view and fill it with data from "feedContent"
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文