【问题标题】:Using retrofit with IMDB API使用 IMDB API 进行改造
【发布时间】:2016-12-31 21:39:50
【问题描述】:

我正在构建一个简单的 IMDB 应用程序,我几乎完成了,只需要一个小细节。 API(http://www.omdbapi.com/) 一次只提供 10 部电影,用户可以指定他们想要的“页面”。我想检索所有条目。我的代码如下所示:

//This populates the list
private void populateList(String title) {
    myAPI.getSearchResults(title, page).enqueue(new Callback<Movies>() {
        @Override
        public void onResponse(Call<Movies> call, Response<Movies> response) {
            movies = response.body().getSearch();
            recyclerView.setAdapter(new ItemAdapter(movies));
            recyclerView.addOnItemTouchListener(
                new ItemClickableListener(getActivity(), new   ItemClickableListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        String id = movies.get(position).getImdbID();
                        showDetails(id, view);
                    }
                }));
        }

        @Override
        public void onFailure(Call<Movies> call, Throwable t) {
            Log.d(TAG, "Error: " + t);
        }
    });
}

在我的界面中:

//For populating the list
@GET("?")
Call<Movies> getSearchResults(@Query("s") String title, @Query("page") int pages);

有一种方法可以知道总共有多少条目,但查询必须至少运行一次才能检索该信息。我尝试使用“do...while”循环修复它并将每批连续的电影添加到列表中,然后填充 RecyclerView 但它不起作用(它会离开循环而不显示任何东西)。也许我忽略了一些东西,这是正确的答案,但即便如此 - 没有更优雅的方法吗?

【问题讨论】:

  • 只是好奇,您使用的是哪个 IMDB api?是免费的吗?
  • 更新了帖子,就我而言它是免费的。
  • 您需要一起获取所有电影吗?所有页面同时? EndlessReycler 没有帮助?

标签: android rest api retrofit imdb


【解决方案1】:

我认为您需要EndlessRecyclerView 来检索十页十页。使用以下代码:

mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mAdapter = new MyAdapter(getActivity(), this);
scrollListener = new EndlessRecyclerOnScrollListener((LinearLayoutManager) mRecyclerView.getLayoutManager()) {
    @Override
    public void onLoadMore(int page) {
        callWebservice(page);
    }
};
mRecyclerView.addOnScrollListener(scrollListener);
mRecyclerView.setAdapter(mAdapter);

callWebservice 完成后,将项目添加到您的列表中:

        @Override
        public void onResponse(Call<List<ShortVideoModel>> call, Response<List<ShortVideoModel>> response) {
             mAdapter.addItems(response.body());
        }

【讨论】:

    【解决方案2】:

    我最终检查了 EndlessRecyclerView,它几乎可以完美运行,但我遇到了一些问题,所以我在这里发布了代码。它不断堆叠监听器和适配器,所以我交换它们。每次插入数据时它也会一直向上滚动,所以我强迫它保持不变,但它有点紧张。

    public class SearchFragment extends Fragment {
    final String TAG = "LOG.SearchFragment";
    final String baseUrl = "http://www.omdbapi.com/";
    Button searchButton;
    EditText searchField;
    RecyclerView recyclerView;
    LinearLayoutManager llm;
    String title = "";
    int page = 1;
    List<Search> movies;
    Gson gson;
    Retrofit retrofit;
    MyAPI myAPI;
    ItemClickableListener listener;
    EndlessRecyclerOnScrollListener scrollListener;
    int firstItem;
    float topOffset;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.d(TAG, "Starting SearchFragment...");
        return inflater.inflate(R.layout.search_fragment, container, false);
    }
    
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    
        //Preparing RecyclerView
        recyclerView = (RecyclerView) getActivity().findViewById(R.id.recycler_view);
        llm = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(llm);
        setOnScrollManager();
    
        //List for the movies
        movies = new ArrayList<>();
    
        //UI
        searchField = (EditText) getActivity().findViewById(R.id.search_field);
        searchButton = (Button) getActivity().findViewById(R.id.search_button);
        searchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!searchField.getText().toString().equals("")) {
                    gson = new GsonBuilder().create();
                    retrofit = new Retrofit.Builder()
                            .baseUrl(baseUrl)
                            .addConverterFactory(GsonConverterFactory.create(gson))
                            .build();
                    myAPI = retrofit.create(MyAPI.class);
                    title = searchField.getText().toString();
                    movies.clear();
                    page=1;
                    setOnScrollManager();
                    fetchMovies(title, page);
                }
            }
        });
    }
    
    private void setOnScrollManager() {
        if (scrollListener!=null) recyclerView.removeOnScrollListener(scrollListener);
        scrollListener = new EndlessRecyclerOnScrollListener((LinearLayoutManager) recyclerView.getLayoutManager()) {
            //This happens when user scrolls to bottom
            @Override
            public void onLoadMore(int newPage) {
                Log.d(TAG, "OnLoadMore "+newPage);
                //Preparing the scroll
                firstItem = llm.findFirstVisibleItemPosition();
                View firstItemView = llm.findViewByPosition(firstItem);
                topOffset = firstItemView.getTop();
    
                //Getting new page
                page=newPage;
                fetchMovies(title, page);
            }
        };
        recyclerView.addOnScrollListener(scrollListener);
    }
    
    //This populates the list
    private void fetchMovies(String title, int page) {
        Log.d(TAG, "Getting "+title+", page "+page);
        myAPI.getSearchResults(title, page).enqueue(new Callback<Movies>() {
            @Override
            public void onResponse(Call<Movies> call, Response<Movies> response) {
                if (movies.size()==0) Toast.makeText(getActivity(), "No movies found", Toast.LENGTH_SHORT).show();
                movies.addAll(response.body().getSearch());
                //We swap the adatper's content when user scrolls down and loads more data
                recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
                recyclerView.swapAdapter(new ItemAdapter(movies), true);
    
                //Scrolling
                Log.d(TAG, "Scrolling to "+firstItem);
                llm.scrollToPositionWithOffset(firstItem, (int) topOffset);
    
                //We avoid stacking up listeners
                if (listener!=null) recyclerView.removeOnItemTouchListener(listener);
                listener = new ItemClickableListener(getActivity(), new   ItemClickableListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        String id = movies.get(position).getImdbID();
                        showDetails(id, view);
                    }
                });
                recyclerView.addOnItemTouchListener(listener);
            }
    
            @Override
            public void onFailure(Call<Movies> call, Throwable t) {
                Log.d(TAG, "Error: " + t);
            }
        });
    }
    
    //This gets the movie details
    private void showDetails(String id, final View view){
        myAPI.getDetails(id).enqueue(new Callback<MovieDetails>() {
            @Override
            public void onResponse(Call<MovieDetails> call, Response<MovieDetails> response) {
                showPopup(response.body(), view);
            }
    
            @Override
            public void onFailure(Call<MovieDetails> call, Throwable t) {
                Log.d(TAG, "Error: " + t);
            }
        });
    }
    
    //This displays the movie details
    private void showPopup(MovieDetails details, View anchorView) {
    
        View popupView = getActivity().getLayoutInflater().inflate(R.layout.popup_layout, null);
    
        PopupWindow popupWindow = new PopupWindow(popupView,
                RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT);
    
        TextView title = (TextView) popupView.findViewById(R.id.movie_detail_title);
        TextView year = (TextView) popupView.findViewById(R.id.movie_detail_year);
        TextView rating = (TextView) popupView.findViewById(R.id.movie_detail_rating);
        TextView director = (TextView) popupView.findViewById(R.id.movie_detail_director);
        TextView stars = (TextView) popupView.findViewById(R.id.movie_detail_stars);
        TextView desc = (TextView) popupView.findViewById(R.id.movie_detail_desc);
    
        title.setText(details.getTitle());
        title.setTextColor(Color.parseColor("#ffffff"));
        year.setText(details.getYear());
        year.setTextColor(Color.parseColor("#ffffff"));
        rating.setText(details.getImdbRating()+"/10");
        rating.setTextColor(Color.parseColor("#ffffff"));
        director.setText("Dir: "+details.getDirector());
        director.setTextColor(Color.parseColor("#ffffff"));
        stars.setText("Stars: "+details.getActors());
        stars.setTextColor(Color.parseColor("#ffffff"));
        desc.setText(details.getPlot());
        desc.setTextColor(Color.parseColor("#ffffff"));
    
        UrlValidator urlValidator = new UrlValidator();
        if (urlValidator.isValid(details.getPoster())) {
            ImageView poster = (ImageView) popupView.findViewById(R.id.movie_detail_poster);
            ImageLoader imageLoader = ImageLoader.getInstance();
            imageLoader.displayImage(details.getPoster(), poster);
        }
    
        // If the PopupWindow should be focusable
        popupWindow.setFocusable(true);
    
        // If you need the PopupWindow to dismiss when when touched outside
        popupWindow.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#CC000000")));
    
        int location[] = new int[2];
    
        // Get the View's(the one that was clicked in the Fragment) location
        anchorView.getLocationOnScreen(location);
    
        // Using location, the PopupWindow will be displayed right under anchorView
        popupWindow.showAtLocation(anchorView, Gravity.NO_GRAVITY,
                location[0], location[1] + anchorView.getHeight());
    
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2017-01-11
      • 2018-09-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-17
      • 2018-01-18
      相关资源
      最近更新 更多