Изображения исчезают при прокрутке Listiew (Android Studio) - PullRequest
0 голосов
/ 18 апреля 2020

ребята.
Я совершенно новичок в программировании и Android программировании, и у меня проблема. Я получаю изображения из MySQL базы данных как InputStream. Затем у меня есть адаптер, куда я загружаю данные, полученные из базы данных, в соответствующие объекты. Ура, listView создан, и все выглядит хорошо! Но ... Когда я прокручиваю вниз / вверх, мои изображения исчезают. Я читал, что listView перерабатывает объекты, но проблема в том, что я не знаю / не понимаю, как я могу решить эту проблему: ///
Пожалуйста, помогите мне, ребята! *

КОРОТКО: изображения исчезают в listView на прокрутке. Слишком много новичков ie, чтобы понять, как это исправить: /

Класс событий

public class Event {

    private int id;
    private String title;
    private Date date;
    private String place;
    private String genre;
    private String description;
    private Double price;

    public Event(int id, String title, Date date, String place, String genre, String description, Double price, InputStream image) {
        this.id = id;
        this.title = title;
        this.date = date;
        this.place = place;
        this.genre = genre;
        this.description = description;
        this.price = price;
        this.image = image;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

    public String getGenre() {
        return genre;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public InputStream getImage() {
        return image;
    }

    public void setImage(InputStream image) {
        this.image = image;
    }

    private InputStream image;

}

Класс адаптера

    public class EventAdapter extends BaseAdapter {

    LayoutInflater mInflater;
    ArrayList<Event> data;

    public EventAdapter(Context c, ArrayList<Event> d){
        mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.data = d;
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

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

    // This is where data is assigned to coresponding fields in event_layout
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        // Hooks
        View view = mInflater.inflate(R.layout.event_layout, null);
        TextView eventName = (TextView) view.findViewById(R.id.eventName);
        TextView dateYear = (TextView) view.findViewById(R.id.dateYear);
        TextView dateDay = (TextView) view.findViewById(R.id.dateDay);
        ImageView image = (ImageView) view.findViewById(R.id.eventImage);

        // Changing date format
        SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy");
        String date = sdf.format(data.get(position).getDate());

        // Extracting date into seprate vars
        String year = date.substring(8);
        String day = date.substring(0, 1).toUpperCase() + date.substring(1, 3) + "." + date.substring(4, 7) + "d.";
        // making Bitmap from InputStream
        Bitmap bmp = BitmapFactory.decodeStream(data.get(position).getImage());

        eventName.setText(data.get(position).getTitle());
        dateYear.setText(year);
        dateDay.setText(day);

        image.setImageBitmap(bmp);

        return view;
    }
}

EventsPage class

    public class EventsPage extends AppCompatActivity {

    private EventAdapter eventAdapter;
    private Context thisContext;
    private ListView eventsListView;
    private TextView progressBar;
    private ArrayList<Event> events = new ArrayList<Event>();

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // Set status bar color to main_green
        if(Build.VERSION.SDK_INT >= 21){
            Window window = this.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                window.setStatusBarColor(this.getResources().getColor(R.color.main_green_color , this.getTheme()));
            }
        }

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_events_page);

        Resources res = getResources();
        eventsListView = (ListView) findViewById(R.id.eventsListView);
        progressBar = (TextView) findViewById(R.id.progressBar);
        thisContext = this;

        progressBar.setText("");

        GetData data = new GetData();
        data.execute("");


    }

    public class GetData  extends AsyncTask<String, String, String> {
        private String msg;
        private ArrayList<Event> bkc_events = new ArrayList<>();
        private ArrayList<Event> tic_events = new ArrayList<>();

        @Override
        protected void  onPreExecute(){
            progressBar.setText("Connecting to database...");
        }

        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected String doInBackground(String... strings) {

            Connection conn = null;
            Statement stmt = null;

            try {
                Class.forName(DBstrings.JDBC_DRIVER);
                conn = DriverManager.getConnection(DBstrings.URL, DBstrings.USERNAME, DBstrings.PASSWORD);

                // Get BKC events
                stmt = conn.createStatement();
                String query = "SELECT * from `bkc_event` ORDER by `date` ASC";
                ResultSet res = stmt.executeQuery(query);

                while(res.next()){
                    Event temp = new Event(res.getInt("ID"), res.getString("title"),
                            res.getDate("date"), res.getString("place"),
                            res.getString("genre"), res.getString("description"),
                            res.getDouble("price"), res.getBinaryStream("image"));
                    this.bkc_events.add(temp);
                }

                res.close();

                // Get TIC events
                query = "SELECT * from `tic_event` ORDER by `date` ASC";
                res = stmt.executeQuery(query);

                while(res.next()){
                    Event temp = new Event(res.getInt("ID"), res.getString("title"),
                            res.getDate("date"), res.getString("place"),
                            res.getString("genre"), res.getString("description"),
                            res.getDouble("price"), res.getBinaryStream("image"));
                    tic_events.add(temp);
                }

                res.close();
                stmt.close();
                conn.close();

                msg = "Process Completed";
                PutDataTogether(bkc_events, tic_events);

            } catch (ClassNotFoundException ex) {
                msg = "Class not found ERROR";
                Log.e("ClassNotFound", ex.getMessage());
            } catch (SQLException ex) {
                msg = "SQL exceltion";
                Log.e("SQL:", ex.getMessage());
            } finally {
                try {
                    if(stmt != null)
                        stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(conn != null)
                        conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            return null;
        }

        // Combine data 2 sets into 1 set
        @RequiresApi(api = Build.VERSION_CODES.N)
        private void PutDataTogether(ArrayList<Event> bkc, ArrayList<Event> tic){

            events.addAll(bkc);

            for (Event t: tic) {
                // counter for showing redundancy
                int counter = 0;
                for(Event r: events){
                    // Check if title and date is the same if so - increase counter by 1
                    if(t.getTitle().toLowerCase().equals(r.getTitle().toLowerCase()) &&
                            t.getDate().equals(r.getDate()))
                        counter++;
                }
                // if counter == 0, then we can add event to final result set
                if(counter == 0)
                    events.add(t);
            }
            events.sort(Comparator.comparing(Event::getDate));
        }

        // To show the data
        @Override
        protected void onPostExecute(String msg){
            progressBar.setText(this.msg);

            /*new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    progressBar.setVisibility(View.INVISIBLE);
                }
            }, 1500);  */


            // We have stuff to display
            if(events.size() > 0){
                eventAdapter = new EventAdapter(thisContext, events);
                eventsListView.setAdapter(eventAdapter);
            }

        }

    } // END of GetDataEvents class

}   // END of EventsPage

Проблема:
Изображение перед прокруткой
Изображение после прокрутка вниз, а затем обратно вверх

1 Ответ

0 голосов
/ 18 апреля 2020

Проблема в методе getView() вашего адаптера. Переработка в ListView означает, что уже существует View, который будет использоваться для отображения ваших значений, поэтому вы не должны раздувать новое. Измените свой код следующим образом:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    // Hooks
    View view = convertView;
    if (view == null) {
        view = mInflater.inflate(R.layout.event_layout, null);
    }

    TextView eventName = (TextView) view.findViewById(R.id.eventName);
    TextView dateYear = (TextView) view.findViewById(R.id.dateYear);
    TextView dateDay = (TextView) view.findViewById(R.id.dateDay);
    ImageView image = (ImageView) view.findViewById(R.id.eventImage);

    // Changing date format
    SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy");
    String date = sdf.format(data.get(position).getDate());

    // Extracting date into seprate vars
    String year = date.substring(8);
    String day = date.substring(0, 1).toUpperCase() + date.substring(1, 3) + "." + date.substring(4, 7) + "d.";
    // making Bitmap from InputStream
    Bitmap bmp = BitmapFactory.decodeStream(data.get(position).getImage());

    eventName.setText(data.get(position).getTitle());
    dateYear.setText(year);
    dateDay.setText(day);

    image.setImageBitmap(bmp);

    return view;
}

Примечание. Я изменил только первые 4 строки метода, чтобы использовать предоставленное представление, которое исходит из ListView, и надувать новое только тогда, когда не существует существующих для повторного использования .

...