通过程序操作除 main_xml 之外的 xml

Posted

技术标签:

【中文标题】通过程序操作除 main_xml 之外的 xml【英文标题】:manipulating xml other then main_xml through program 【发布时间】:2019-01-14 06:42:33 【问题描述】:

我正在创建一个图像下载应用程序,它获取图像 URL、下载图像并将它们显示在列表视图中。为此,我正在通过程序操作 xml。问题是我如何通过程序操作不是我的主要 xml 文件的 xml 文件。

ImageDownloader 类:

public class ImageDownloader extends AsyncTask<String, Void, Bitmap> 

    private ImageView imageView;
    private ProgressBar progressBar;

    public ImageDownloader(ImageView imageView, ProgressBar progressBar) 
        this.imageView = imageView;
        this.progressBar = progressBar;
    

    @Override
    protected void onPreExecute() 
        super.onPreExecute();
        imageView.setVisibility(View.GONE);
        progressBar.setVisibility(View.VISIBLE);
    

    @Override
    protected Bitmap doInBackground(String... params) 

        try
            URL url = new URL(params[0]);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            if(connection.getContentType().contains("image"))
                InputStream inputStream = connection.getInputStream();
                return BitmapFactory.decodeStream(inputStream);
            
        
        catch(Exception e)
            e.printStackTrace();
        
        return null;
    

    @Override
    protected void onPostExecute(Bitmap bitmap) 
        super.onPostExecute(bitmap);
        try 
            imageView.setImageBitmap(bitmap);
            progressBar.setVisibility(View.GONE);
            imageView.setVisibility(View.VISIBLE);
         catch (Exception e) 
            e.printStackTrace();
        
    

ImageUI 类:

public class ImageUI 

    private Context context;
    private ArrayList<String> urls;

    private ImageView imageView;
    private ProgressBar progressBar;
    private RelativeLayout relativeLayout;

    public ImageUI(Context context, ArrayList<String> urls, RelativeLayout relativeLayout) 
        this.context = context;
        this.urls = urls;
        this.relativeLayout = relativeLayout;
    

    private void buildUI()
        imageView = new ImageView(context);
        imageView.setVisibility(View.GONE);

        progressBar = new ProgressBar(context);
        progressBar.setIndeterminate(true);
        progressBar.setVisibility(View.GONE);

        relativeLayout = new RelativeLayout(context);
        relativeLayout.setGravity(1);
        relativeLayout.addView(imageView);
        relativeLayout.addView(progressBar);

    

    public RelativeLayout downloadImages()
        int i = 0;
        while(i < urls.size())
            buildUI();

            ImageDownloader imageDownloader = new ImageDownloader(imageView, progressBar);

            imageDownloader.execute(urls.get(i));

            imageDownloader = null;

            i++;

            return relativeLayout;
        
        return null;
    

RowItem 类:

public class RowItem 

    private RelativeLayout relativeLayout;

    public RowItem(RelativeLayout relativeLayout) 
        this.relativeLayout = relativeLayout;
    

    public RelativeLayout getRelativeLayout() 
        return relativeLayout;
    

    public void setRelativeLayout(RelativeLayout relativeLayout) 
        this.relativeLayout = relativeLayout;
    

CustomListViewAdapter 类:

public class CustomListViewAdapter extends ArrayAdapter<RowItem>

    Context context;

    public CustomListViewAdapter(Context context, int resourseID, List<RowItem> items)
        super(context, resourseID, items);
        this.context = context;
    

    private class ViewHolder
        RelativeLayout relativeLayout;
    

    public View getView(int position, View convertView, ViewGroup parent)
        ViewHolder holder = null;

        RowItem rowItem = getItem(position);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

        if(convertView == null)
            convertView = inflater.inflate(R.layout.list_item, null);
            holder = new ViewHolder();
            holder.relativeLayout = (RelativeLayout) convertView.findViewById(R.id.relativeLayout);
            convertView.setTag(holder);
        
        else
            holder = (ViewHolder) convertView.getTag();
        
        return convertView;
    

MainActivity 类:

public class MainActivity extends AppCompatActivity 

    ArrayList<RelativeLayout> images;

    ArrayList<String> urls = new ArrayList<>();

    RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);

    List<RowItem> rowItems;
    ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        addUrls();

        images = new ArrayList<>();

        for (int i = 0; i < urls.size(); i++) 
            ImageUI imageUI = new ImageUI(this, urls, relativeLayout);

            images.add(imageUI.downloadImages());
        

        rowItems = new ArrayList<>();
        for (int i = 0; i < images.size(); i++) 
            RowItem item = new RowItem(images.get(i));
            rowItems.add(item);
        

        listView = (ListView) findViewById(R.id.listView);
        CustomListViewAdapter adapter = new CustomListViewAdapter(this,
                R.layout.list_item, rowItems);
        listView.setAdapter(adapter);

    

    public void addUrls() 

        urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTXEZRoYOhIJxL5foNz_NlatDlgYStzZgVIiKuo6vtRtz2wY-8b4Q");
        urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSFL3WYbqNOX-dwjtT1LroBlY5W-3YuwSIuCMRaLpnjMXbVPEJy");
        urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQiwgrJeAJN-7lcy92N51uP7XzccK_p-fTSJNCXPLPSVih8wqPf");
        urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT19dYLCEZlMRqojedJB-05jTrflD74nasvkXs-SdVeyM2BEpCSFA");
        urls.add("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg");
        urls.add("https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg");
        urls.add("https://images.unsplash.com/photo-1418489098061-ce87b5dc3aee?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=2f033882f3c25404e3f904fbfe2351be&w=1000&q=80");
        urls.add("https://techcrunch.com/wp-content/uploads/2018/03/gettyimages-705351545.jpg?w=730&crop=1");

    

此代码给出错误:

08-07 13:29:31.865 17741-17741/com.example.danishrizvi.test3 E/MemoryLeakMonitorManager: MemoryLeakMonitor.jar is not exist!
08-07 13:29:31.916 17741-17741/? E/androidRuntime: FATAL EXCEPTION: main
                                                   Process: com.example.danishrizvi.test3, PID: 17741
                                                   java.lang.RuntimeException: Unable to instantiate activity ComponentInfocom.example.danishrizvi.test3/com.example.danishrizvi.test3.MainActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3092)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
                                                       at android.app.ActivityThread.-wrap12(Unknown Source:0)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
                                                       at android.os.Handler.dispatchMessage(Handler.java:108)
                                                       at android.os.Looper.loop(Looper.java:166)
                                                       at android.app.ActivityThread.main(ActivityThread.java:7425)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
                                                    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
                                                       at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:120)
                                                       at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:155)
                                                       at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:31)
                                                       at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:55)
                                                       at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java:33)
                                                       at android.support.v7.app.AppCompatDelegateImplN.<init>(AppCompatDelegateImplN.java:33)
                                                       at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:201)
                                                       at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:185)
                                                       at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
                                                       at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190)
                                                       at com.example.danishrizvi.test3.MainActivity.<init>(MainActivity.java:18)
                                                       at java.lang.Class.newInstance(Native Method)
                                                       at android.app.Instrumentation.newActivity(Instrumentation.java:1178)
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3082)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302) 
                                                       at android.app.ActivityThread.-wrap12(Unknown Source:0) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:108) 
                                                       at android.os.Looper.loop(Looper.java:166) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:7425) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 

在这一行:

RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);

【问题讨论】:

【参考方案1】:

移动

RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);

里面

onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout)
    addUrls();
    // the rest of your code

您需要先调用setContentView,然后才能使用findViewById,或者换句话说:您需要先扩充View,然后才能在其中搜索子视图。 这是因为,在内部,findViewById 确实在做getWindow().findViewById(id)

【讨论】:

这消除了错误,应用程序运行成功,但应用程序是空白的,什么都不显示? @SyedDanish 这是因为您没有在 CustomListViewAdapter 的 getView 方法中对 RecyclerView 项目设置任何内容。您需要沿 holder.image.setImageBitmap(image) 行添加一些内容,并对 R.layout.list_item 中的每个视图执行相同操作。您将在this answer 中找到一个工作示例。我希望它有所帮助;)

以上是关于通过程序操作除 main_xml 之外的 xml的主要内容,如果未能解决你的问题,请参考以下文章

IDA Pro:如何通过删除除代码之外的所有内容来减少内存快照大小?

Cocos2d 应用程序可在除 iPhone 4(任何操作系统)之外的所有设备上运行,CCBatchnode 在 addchild 后仅显示黑屏

从文本框中删除除电子邮件地址之外的所有内容

Android:onResume() 正在跳转到除异常之外的另一个活动

移动查勘通赔版本系统上线-对接理赔失败,导致案件无法正常下发及处理

除了被零除之外,还都有哪些情况会发生浮点异常?