【问题标题】:Learning MVP for Android and not sure what I am doing wrong学习适用于 Android 的 MVP,但不确定我做错了什么
【发布时间】:2020-08-25 17:45:33
【问题描述】:

我正在学习适用于 Android 的 MVP。我构建了一个使用 RecyclerView、Retrofit 的简单应用程序,并且我正在使用免费的 Pokemon API 来加载 Pokemon 名称。下面是我的代码。请让我知道我做错了什么。应用程序运行时出现空白屏幕。下面是我的类和 XMLs

主要活动的xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/main_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

RecyclerView 项目 xml。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
    android:id="@+id/pokemon_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="50dp"
    android:textSize="25sp">
    </TextView>

</LinearLayout>

主活动:

public class MainActivity extends AppCompatActivity implements MainContract.MainView {

    RecyclerView recyclerView;
    RVAdapter rvAdapter;
    MainContract.MainPresenter mainPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mainPresenter = new MainPresenter(this);

    recyclerView = findViewById(R.id.main_rv);
    RecyclerView.LayoutManager manager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(manager);
    mainPresenter.getData();
    }

    @Override
    public void loadDataInList(List<Pokemon> pokemonList) {
    rvAdapter = new RVAdapter(pokemonList);
    recyclerView.setAdapter(rvAdapter);

    }
}

Presenter MainContract 的接口:

public interface MainContract {
    interface MainView{
       void loadDataInList(List<Pokemon> pokemonList);

    }
    interface MainPresenter {
       void getData();
    }
}

Presenter 类 MyPresenter:

public class MyPresenter implements MainContract.MainPresenter {

    MainContract.MainView mainView;

    String  BASE_URL = "https://pokeapi.co/api/v2/";

    public MyPresenter(MainContract.MainView mainView) {
    this.mainView = mainView;
    }

    @Override
    public void getData() {

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    PokeService pokeService = retrofit.create(PokeService.class);
    Call<PokemonResponse> call = pokeService.getPokemons();
    call.enqueue(new Callback<PokemonResponse>() {
        @Override
        public void onResponse(Call<PokemonResponse> call, Response<PokemonResponse> response) {
        if (response.isSuccessful()){
            PokemonResponse pokemonResponse = response.body();

            ArrayList<Pokemon> pokemonArrayList = (ArrayList<Pokemon>) pokemonResponse.getResults();

            mainView.loadDataInList(pokemonArrayList);
         }else
            Log.e(TAG, "onResponse: " + response.errorBody());
        }

        @Override
        public void onFailure(Call<PokemonResponse> call, Throwable t) {

        }
    });

    }
}

型号

public class PokemonResponse {

    int count;
    String next;
    boolean previous;
    private ArrayList<Pokemon> results;

    public int getCount() {
    return count;
    }

    public void setCount(int count) {
    this.count = count;
    }

    public String getNext() {
    return next;
    }

    public void setNext(String next) {
    this.next = next;
    }

    public boolean isPrevious() {
    return previous;
    }

    public void setPrevious(boolean previous) {
    this.previous = previous;
    }

    public List<Pokemon> getResults() {
    return results;
    }

    public void setResults(ArrayList<Pokemon> results) {
    this.results = results;
    }
}

型号

public class Pokemon {
    private String name;

    public Pokemon(String name) {
    this.name = name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getName() {
    return name;
    }
}

API 服务:

public interface PokeService {

    @GET("/pokemon")
    Call<PokemonResponse> getPokemons();
}

RecyclerView 适配器

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PokemonNamesViewHolder> {

    List<Pokemon> pokemonList;



    public RVAdapter(List<Pokemon> pokemonList) {
    this.pokemonList = pokemonList;
    }

    @Override
    public PokemonNamesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
    View view = layoutInflater.inflate(R.layout.rv_item, parent, false);
    return new  PokemonNamesViewHolder(view);
    }

    @Override
    public void onBindViewHolder(PokemonNamesViewHolder holder, int position) {
    Pokemon pokemon = pokemonList.get(position);
    holder.textView.setText(pokemon.getName());

    }

    @Override
    public int getItemCount() {
    return pokemonList.size();
    }

    public class PokemonNamesViewHolder extends   RecyclerView.ViewHolder{
    public TextView textView;


    public PokemonNamesViewHolder( View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.pokemon_name);
    }
    }
}

应用程序没有崩溃,我在清单中设置了 Internet 权限,并在 gradle 中添加了依赖项。

json 对象:

{
    "count": 964,
    "next": "https://pokeapi.co/api/v2/pokemon?offset=20&limit=20",
    "previous": null,
    "results": [
        {
            "name": "bulbasaur",
            "url": "https://pokeapi.co/api/v2/pokemon/1/"
        },
        {
            "name": "ivysaur",
            "url": "https://pokeapi.co/api/v2/pokemon/2/"
        },
        {
            "name": "venusaur",
            "url": "https://pokeapi.co/api/v2/pokemon/3/"
        }

    ]
}

【问题讨论】:

  • 你确定API调用和响应解析成功
  • @CôngHải Hải 我在上面添加了 API。
  • 在 onFailure 中请添加 t.printStackTrace() 这样您将在 logcat 中看到错误(如果有)。让我知道是什么错误

标签: java android android-recyclerview retrofit mvp


【解决方案1】:

据我所知,当你将 loadData 设置为 recyclerview 时,你做了类似

    @Override
    public void loadDataInList(List<Pokemon> pokemonList) {
        rvAdapter = new RVAdapter(pokemonList);
        recyclerView.setAdapter(rvAdapter);
    }

此步骤仅意味着您将适配器设置为您的 recyclerview,但是您忘记通知您 recyclerview 数据已更改。

您可以在 setadapter 行之后添加类似 rvAdapter.notifyDataChanged() 的内容来测试它。

【讨论】:

  • 我尝试添加 rvAdapter.notifyDataChanged(),但仍然得到相同的结果。
  • 没关系。他一开始没有设置数据,也没有设置适配器。所以没有什么可更新的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
  • 2017-09-29
  • 2011-12-04
  • 2011-01-27
  • 2015-08-18
相关资源
最近更新 更多