java - 为什么 Adapter 多次向 ListView 添加相同的位置?

标签 java android xml

enter image description here

不确定它有多清晰,但我遇到的问题是我的适配器多次从 TreeMap 添加相同的位置。这不应该发生/它多次添加同一部电影。

我查看了代码并尝试遵循代码的循环,但我似乎找不到问题。

我已经对我的代码进行了 Gists,因为它太长了,我不想让页面成为垃圾邮件。

如果你们真的想要这一切,我会更新我的问题。

我的应用程序向 API 发出请求并获取电影 ID、标题、信息、海报等的 TreeMap。这个特殊问题出在我的 ListViewAdaptor 上。

MainActivityFragment.java

ListViewAdaptor.java

MainActivity.java

fragment_main.xml

activity_main.xml

results_layout.xml

HttpHandler.java

ListView 适配器

package com.example.zdroa.fetchmovies;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.util.TreeMap;

class ListViewAdaptor extends BaseAdapter {

    private Context mContext;
    private TreeMap<Integer, String> urls;
    private TreeMap<Integer, String> titles;

    ListViewAdaptor(Context context, TreeMap<Integer, String> URLS, TreeMap<Integer, String> TITLES) {
        mContext = context;
        urls = URLS;
        titles = TITLES;
    }

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

    @Override
    public Object getItem(int position) {
        return null;
    }

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

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

        if (convertView == null) {
            convertView = View.inflate(mContext, R.layout.results_layout, null);
        }
        ImageView imageView = (ImageView) convertView.findViewById(R.id.ivPosters);
        TextView textView = (TextView) convertView.findViewById(R.id.results_layout_tv_movie_name);

        Drawable d = mContext.getResources().getDrawable(R.drawable.place_holder_img);


        String link_end = urls.ceilingEntry(position).getValue();
        String title = titles.ceilingEntry(position).getValue();

        Picasso.with(mContext)
                .load("http://image.tmdb.org/t/p/w185" + link_end)
                .placeholder(d)
                .into(imageView);

        textView.setText(title);


        return convertView;
    }
}

MainActivityFragment.java

package com.example.zdroa.fetchmovies;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.TreeMap;

public class MainActivityFragment extends Fragment {

    private static String API_KEY = "b692b9da86f1cf0c1b623ea6e2770101";

    ListView listView;
    Button button;

    static TreeMap<Integer, Integer> IDS;
    static TreeMap<Integer, String> TITLES;
    static TreeMap<Integer, String> POSTERS;
    static TreeMap<Integer, String> GENRES;
    static TreeMap<Integer, String> PRODUCTION_COUNTRIES;
    static TreeMap<Integer, String> OVERVIEW;
    static TreeMap<Integer, String> RUNTIME;

    public MainActivityFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        listView = (ListView) rootView.findViewById(R.id.lvMovies);

        new ImageLoadTask().execute();

        //if fragment is visible
        if (getActivity() != null) {


            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    System.out.println(TITLES.ceilingEntry(position).getValue());
                }
            });
        }
        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();

    }

    private class ImageLoadTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            IDS = new TreeMap<>();

            IDS.put(1, 2);
            IDS.put(2, 3);
            IDS.put(3, 5);
            IDS.put(4, 6);
            IDS.put(5, 8);
            IDS.put(6, 9);
            IDS.put(7, 11);
            IDS.put(8, 12);
            IDS.put(9, 13);
            IDS.put(10, 14);


            populateTreeMaps();


            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            if (getActivity() != null) {
                ListViewAdaptor adapter = new ListViewAdaptor(getActivity(), POSTERS, TITLES);
                listView.setAdapter(adapter);

                System.out.println(POSTERS);
                System.out.println(TITLES);
            }
        }

        private Void populateTreeMaps() {
            HttpHandler httpHandler = new HttpHandler();

            TITLES = new TreeMap<>();
            POSTERS = new TreeMap<>();

            for (int i = 0; i < IDS.size(); i++) {
                String jsonString = httpHandler.makeServiceCall("https://api.themoviedb.org/3/movie/" + IDS.ceilingEntry(i).getValue() + "?api_key=" + API_KEY);

                if (jsonString != null) {
                    try {
                    //POPULATE ALL THE GRAPHS HERE
                        getTitles(jsonString, IDS.ceilingEntry(i).getValue());
                        getPosterURLs(jsonString, IDS.ceilingEntry(i).getValue());

                    } catch (JSONException e) {
                        return null;
                    }
                }
            }
            return null;
        }

        private void getTitles(String JSONString, Integer mov_id) throws JSONException {
            JSONObject jsonObject = new JSONObject(JSONString);

            String title = jsonObject.getString("title");

            TITLES.put(mov_id, title);
        }

        private void getPosterURLs(String JSONString, Integer mov_id) throws JSONException {
            JSONObject jsonObject = new JSONObject(JSONString);

            String url = jsonObject.getString("poster_path");

            POSTERS.put(mov_id, url);
        }

        private void getYoutubeLink() {
        }
    }
}

最佳答案

您的键->值逻辑有问题。

您使用的 TreeMap 填充了具有间隙 [2,3,5,6, etc] 的键,然后在适配器中您尝试按位置获取项目,显然您的 map 不包含您想要的每个位置的项目,所以你的 ceilingEntry() 返回下一个项目 key >= requested_key

请参阅此说明:https://www.tutorialspoint.com/java/util/treemap_ceilingentry.htm

最简单和最直接的解决方案是移动到 List<Movie>其中 Movie 是一个新的模型类,它包含您需要在适配器中显示的所有数据(url、标题...)。

关于java - 为什么 Adapter 多次向 ListView 添加相同的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43976318/

相关文章:

xml - groovy 创建新的 xml 节点

java - Java中最小值始终显示为0

java - 绘制形状时,形状属性未在类之间正确传递 - Java Swing

java 到 mysql。我需要从字符串参数转换为时间戳

android - 使用Maven apklib时出现编译错误

javascript - 使用 qml 读取多个 Xml 属性

java - 如何从文件加载 Java 枚举元素的值

java - Quarkus Rest Client 不在 ClientHeadersFactory 的实现中注入(inject) ConfigProperty

android - getView()在getDrawable()中崩溃

java - 由于 Kotlin 中未解析的引用,无法设置文本或可绘制对象