Java 图像在listview中消失

Java 图像在listview中消失,java,android,listview,Java,Android,Listview,我的应用程序使用ListView显示url中的一些图像和标题。但无论我做什么,图像在向上或向下滚动后从列表视图中消失,没有人能再次看到它们。 我该怎么做?我是android新手,所以我很乐意看到任何建议 我的代码在这里: AndroidManifest: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"

我的应用程序使用
ListView
显示url中的一些图像和标题。但无论我做什么,图像在向上或向下滚动后从
列表视图中消失,没有人能再次看到它们。
我该怎么做?我是android新手,所以我很乐意看到任何建议

我的代码在这里:

AndroidManifest:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.forwork">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.java:

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Objects;
import java.util.concurrent.ExecutionException;

public class MainActivity extends Activity{

    public final static int SIZE=30;

    public String[] titles = new String[SIZE];          //array for titles
    public String[] keys = new String[SIZE];            //array for id of news
    public String[] image_url = new String[SIZE];       //array for image urls to download
    public String data="";
    //that's for parsing
    JSONObject news = null;
    String title = "";
    JSONObject prefs = null;
    JSONObject inner = null;
    JSONObject elements = null;
    JSONObject image =null;
    String pic = "";
    JSONObject json = null;
    JSONArray collection = null;
    JSONObject documents = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (isInternetThere(this))                                          //if internet is not absent
            try {
                ListView my_list_view = (ListView) findViewById(R.id.list_view);    //custom list view
                CustomList adapter = new CustomList(this,titles,image_url);         //custom adapter
                my_list_view.setAdapter(adapter);
                Parse p = new Parse();                                               //instance of my async task for getting json
                data = p.execute().get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        else {
            Toast.makeText(this, "No internet connection", Toast.LENGTH_LONG).show();
            finish();
        }

        try {
            json = new JSONObject(data);                                    //parsing json
            collection = json.getJSONArray("collection");                   //new's ids
            documents = json.getJSONObject("documents");                    //new's info
            for (int i=0; i<keys.length;i++){
                keys[i]=collection.getString(i);
                news = documents.getJSONObject(keys[i]);
                title = news.getString("title");                            //title
                titles[i]=title;                                            //put title into list
                prefs = news.getJSONObject("prefs");
                inner = prefs.getJSONObject("inner");
                elements = inner.getJSONObject("elements");
                image = elements.getJSONObject("image");
                if (image.has("small_url"))                                 //whether there is a picture?
                    pic = image.getString("small_url");
                else pic = "";
                image_url[i] = pic;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {           //it is just for orientation monitoring
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
        }
    }

    public class Parse extends AsyncTask<Void,Void,String> {                //my async task #1 that just get a json from url

        @Override
        protected String doInBackground(Void... params) {
            String str= null;
            try {
                str = readJSON();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return str;
        }

        public String readJSON() {                                          //function that get json
            HttpURLConnection urlConnection = null;
            BufferedReader reader = null;
            String resultJson = "";                                         //this will be a string with json
            try {
                URL url = new URL("https://meduza.io/api/v3/search?chrono=news&page=0&per_page=30&locale=ru");      //url with 30 news

                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();

                InputStream inputStream = urlConnection.getInputStream();       //stream for getting json
                StringBuffer buffer = new StringBuffer();                       //buffer for json saving

                reader = new BufferedReader(new InputStreamReader(inputStream));        //it just reads

                String line;
                while ((line = reader.readLine()) != null) {                            //line by line..
                    buffer.append(line);                                                //...and add it into buffer
                }

                resultJson = buffer.toString();                                 //result is string got from buffer

            } catch (Exception e) {
                e.printStackTrace();
            }
            return resultJson;
        }
    }

    public class DownloadImage extends AsyncTask<String,Void,Bitmap>{               //my async task #2 for downloading image from url using Bitmap
        private final WeakReference<ImageView> imgv;                                //it means that..
        public DownloadImage(ImageView imageView){
            imgv = new WeakReference<ImageView>(imageView);                        //the object can be deleted by garbage collector without any trubles
        }                                                                          //it helps to avoid memory leaks

        @Override
        protected Bitmap doInBackground(String... strings) {
            return down_Bit(strings[0]);
        }

        @Override
        protected void onPostExecute(Bitmap res){
            if (isCancelled()){
                res=null;
            }

            if(imgv != null){                                                       //if the link is actual...
                ImageView iv = imgv.get();                                          //we get it
                if (iv != null){                                                    //if the object is exists...
                    if (res != null)                                                //and image exests...
                        iv.setImageBitmap(res);                                     //we show it

                }
            }
        }

        private Bitmap down_Bit(String url){                                        //it is for downloading images
            HttpURLConnection urlConnection = null;
            try{
                URL uri = new URL(url);
                urlConnection = (HttpURLConnection) uri.openConnection();
                int statusCode = urlConnection.getResponseCode();
                if (statusCode != HttpStatus.SC_OK)                                 //if our url is not right(for ex. "http" instead of "https"
                    return null;

                InputStream is = urlConnection.getInputStream();
                if (is != null){
                    Bitmap bitmap = BitmapFactory.decodeStream(is);                 //if input stream exists we get the Bitmap from it....
                    return bitmap;                                                  //and return it
                }
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                if (urlConnection != null)
                    urlConnection.disconnect();
            }
            return null;
        }
    }

    public class CustomList extends ArrayAdapter<String>{                           //that is my custom adapter named CustomList. probably for not misunderstanding
        private Activity context;
        private String[] item_name;
        private String[] imgurl;

        public CustomList(Activity context,String[] item_name, String[] imgurl){        //constructor
            super(context,R.layout.my_listview_item,item_name);
            this.context=context;               //activity
            this.item_name=item_name;           //there is will be the titles
            this.imgurl=imgurl;                 //there is will be the images
        }

        @Override
        public int getCount(){
            return item_name.length;
        }

        @Override
        public String getItem(int position){
            return item_name[position];
        }

        @Override
        public long getItemId(int position){
            return position;
        }

        public View getView(int position, View view, ViewGroup parent) {
            LayoutInflater inflater = context.getLayoutInflater();
            View rowView = inflater.inflate(R.layout.my_listview_item,null,true);

            TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);


            if (imgurl[position] != "") {                                               //if there is a url of an image(because there some news without it)
                rowView.findViewById(R.id.img).setVisibility(View.VISIBLE);             //show the picture slot
                imgurl[position] = "https://meduza.io" + imgurl[position];              //and make the url absolute, not relative
                new DownloadImage((ImageView) rowView.findViewById(R.id.img)).execute(imgurl[position]);        //and download the picture using the absolute url
            }
            else
                rowView.findViewById(R.id.img).setVisibility(View.GONE);                //if there is no picture, just hide the slot
            txtTitle.setText(item_name[position]);                                      //it is title

            return rowView;
        }
    }

    public boolean isInternetThere(Context context) {                                   //it is for internet connection testing
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            return true;
        } else {
            return false;
        }
    }
}
导入android.app.Activity;
导入android.content.Context;
导入android.content.res.Configuration;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.net.ConnectivityManager;
导入android.net.NetworkInfo;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.ImageView;
导入android.widget.ListView;
导入android.widget.TextView;
导入android.widget.Toast;
导入org.apache.http.HttpStatus;
导入org.json.JSONArray;
导入org.json.JSONException;
导入org.json.JSONObject;
导入java.io.BufferedReader;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.lang.ref.WeakReference;
导入java.net.HttpURLConnection;
导入java.net.URL;
导入java.util.Objects;
导入java.util.concurrent.ExecutionException;
公共类MainActivity扩展了活动{
公共最终静态整数大小=30;
public String[]titles=新字符串[SIZE];//标题数组
public String[]keys=新字符串[SIZE];//用于新闻id的数组
public String[]image_url=new String[SIZE];//用于下载图像url的数组
公共字符串数据=”;
//这是用于解析的
JSONObject news=null;
字符串标题=”;
JSONObject prefs=null;
JSONObject内部=null;
JSONObject元素=null;
JSONObject image=null;
字符串pic=“”;
JSONObject json=null;
JSONArray集合=null;
JSONObject documents=null;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(isInternetThere(this))//如果没有互联网
试一试{
ListView我的列表视图=(ListView)findViewById(R.id.list\u视图);//自定义列表视图
CustomList adapter=新的CustomList(这个,标题,图像_url);//自定义适配器
my_list_view.setAdapter(适配器);
Parse p=new Parse();//获取json的异步任务的实例
data=p.execute().get();
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
否则{
Toast.makeText(这是“没有互联网连接”,Toast.LENGTH_LONG.show();
完成();
}
试一试{
json=新JSONObject(数据);//解析json
collection=json.getJSONArray(“collection”);//新的ID
documents=json.getJSONObject(“documents”);//new的信息

对于(int i=0;i我认为您使用的是
ListView
。在
ListView
中,在滚动时,Android会重新使用列表项,因此当您滚动时,图像开始消失

因此,您需要做的第一个更改是在
ListView
上使用
RecyclerView
RecyclerView
实现将强制您实现
ViewHolder
模式,这将使您的滚动体验更好!查看此列表以了解更多信息

最后,要使图像按需工作,我建议您使用。这是可用的最佳图像加载库。您不需要维护列表中元素的位置,图像将按需工作

我建议使用一个库,因为自己实现图像加载最佳实践可能需要很多时间。您必须维护图像缓存,有效维护位图大小等


希望以下几点能够指导您以最好的方式实现您的图像滚动列表:)干杯!

我认为您使用的是
ListView
。在
ListView
中,当您滚动时,安卓会重新使用列表项,因此当您滚动图像时,图像开始消失

因此,您需要做的第一个更改是在
ListView
上使用
RecyclerView
RecyclerView
实现将强制您实现
ViewHolder
模式,这将使您的滚动体验更好!查看此列表以了解更多信息

最后,要使图像按需工作,我建议您使用。这是可用的最佳图像加载库。您不需要维护列表中元素的位置,图像将按需工作

我建议使用一个库,因为自己实现图像加载最佳实践可能需要很多时间。您必须维护图像缓存,有效维护位图大小等


希望以下几点能够指导您以最佳方式实现图像滚动列表:)干杯!

非常感谢您的帮助,我将尝试您的解决方案:)@KapitanBanann请向上投票并选择答案(如果有帮助的话):)是的,谢谢:)我尝试了库,但它没有加载图像。我断言,这是我的错,但您能给我举个例子吗我怎样才能与毕加索合作?我想我应该这样做:
Picasso.with(context).load(imgurl[position]).fit().into((ImageView)rowView.findViewById(R.id.img));
而不是:
新建下载图像((ImageView)rowView.findViewById(R.id.img))。执行(imgurl[position]);
我对不对?听起来不错。尝试继续搜索