-1

i am creating an image downloading app that takes image urls, downloads images and displays them in a listview. For this i am manipulating the xml through program. the question is how i can manipulate an xml file that is not my main xml file through program.

ImageDownloader Class:

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 Class:

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 Class:

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 Class:

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 Class:

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");

    }
}

this code gives error:

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 ComponentInfo{com.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) 

at this line:

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

1 Answers1

1

Move

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

inside

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
}

You need a call to setContentView before you can use findViewById, or in other words: you need to inflate a View before searching child views within it. This is because, internally, findViewById is really doing getWindow().findViewById(id)

2Dee
  • 8,609
  • 7
  • 42
  • 53
  • this removed the error and the app ran successfully but the app is blank and shows nothing? – Syed Danish Aug 07 '18 at 08:55
  • 1
    @SyedDanish that is because you are not setting any content on your RecyclerView items in the getView method of your CustomListViewAdapter. You would need to add something along the lines of holder.image.setImageBitmap(image) and do the same for every View you have in your R.layout.list_item. You will find a working example in [this answer](https://stackoverflow.com/a/24865351/1178337). I hope it helps ;) – 2Dee Aug 07 '18 at 09:05