使用android分页库的java动态查询

pgpifvop  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(326)

我正在制作一个新闻应用程序,我正在为我的新闻回收视图使用分页库。我想根据类别显示新闻。我正在从对话框中选择类别,并将其分配给主活动内的texview。这是我的应用程序。我想观察该值并根据该值动态发送请求。我正在使用改装作为网络库。
主活动.java

public class MainActivity extends AppCompatActivity{

private MainActivityViewModel mViewModel;
private NewsAdapter mAdapter;
//widgets
@BindView(R.id.recyclerView)
RecyclerView mRecyclerView;
@BindView(R.id.toolbar)
MaterialToolbar toolbar;
@BindView(R.id.searchView)
SearchView mSearchView;
@BindView(R.id.categoryTv)
TextView categoryTv;
private String [] categoryArray;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    mAdapter = new NewsAdapter(this);
    categoryArray=getResources().getStringArray(R.array.category_array);
    mViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this
            .getApplication())).get(MainActivityViewModel.class);
    setSupportActionBar(toolbar);
    initRecyclerView();
    observeViewModel();
    mRecyclerView.setAdapter(mAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_toolbar_menu,menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    int id=item.getItemId();
    if(id==R.id.category){
        Dialog d=new Dialog(this);
        d.setContentView(R.layout.number_picker);
        Button selectBtn=d.findViewById(R.id.select);
        NumberPicker np=d.findViewById(R.id.numberPicker);
        np.setMinValue(0);
        np.setTextColor(getResources().getColor(R.color.colorPrimary));
        np.setMaxValue(categoryArray.length-1);
        np.setDisplayedValues(categoryArray);
        np.setWrapSelectorWheel(false);
        selectBtn.setOnClickListener(v -> {
            categoryTv.setText(categoryArray[np.getValue()]);
            d.dismiss();
        });
        d.show();
    }
    return super.onOptionsItemSelected(item);
}
private void initRecyclerView(){
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(layoutManager);
}
private void observeViewModel() {
    mViewModel.newsPagedList.observe(this, newsModels -> {
        mAdapter.submitList(newsModels);
    });
  mRecyclerView.setAdapter(mAdapter);
} 
}

mainactivityviewmodel.java

public class MainActivityViewModel extends AndroidViewModel {

private LiveData<NewsDataSource> liveDataSource;

public LiveData<PagedList<NewsModel>> newsPagedList;

public MainActivityViewModel(Application application) {
    super(application);
    init();
}
private void init() {
    NewsDataSourceFactory newsFactory=new NewsDataSourceFactory();
    liveDataSource=newsFactory.getNewsDataSourceMutableLiveData();
    PagedList.Config config=new PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setPageSize(PAGE_SIZE)
            .build();
    newsPagedList=new LivePagedListBuilder<>(newsFactory,config).build();
}
}

新闻数据源.java

public class NewsDataSource extends PageKeyedDataSource<Integer, NewsModel> {
Single<Response> mResponse;
List<NewsModel> newsResponse;
@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, NewsModel> callback) {
    RetroService service = RetroService.getInstance();

    mResponse = service.getData(FIRST_PAGE, PAGE_SIZE, "us", API_KEY,"general");
    mResponse.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new SingleObserver<Response>() {
                @Override
                public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {

                }

                @Override
                public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull Response response) {
                    newsResponse = response.getNewsList();
                    callback.onResult(newsResponse, null, FIRST_PAGE + 1);
                }

                @Override
                public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {

                }
            });
}

@Override
public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, NewsModel> callback) {
    RetroService service = RetroService.getInstance();
    mResponse = service.getData(FIRST_PAGE, PAGE_SIZE, "us", API_KEY,"general");//Want to change that general data dynamically.
    mResponse.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new SingleObserver<Response>() {
                @Override
                public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {

                }

                @Override
                public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull Response response) {
                    newsResponse = response.getNewsList();
                    if (newsResponse != null) {
                        int key;
                        if (params.key > 1) {
                            key = params.key - 1;
                        } else {
                            key = 0;
                        }
                        callback.onResult(newsResponse, key);
                    }
                }

                @Override
                public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {

                }
            });
}

@Override
public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, NewsModel> callback) {
    RetroService service = RetroService.getInstance();
         mResponse = service.getData(params.key, PAGE_SIZE, "us",API_KEY,"general");
    mResponse.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new SingleObserver<Response>() {
                @Override
                public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {

                }

                @Override
                public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull Response response) {
                    newsResponse = response.getNewsList();
                    if (newsResponse != null) {
                        callback.onResult(newsResponse, params.key + 1);
                    }
                }
                @Override
                public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {

                }
            });
}
}

新闻数据源工厂.java

public class NewsDataSourceFactory extends DataSource.Factory<Integer, NewsModel> {
private MutableLiveData<NewsDataSource> newsDataSourceMutableLiveData;
NewsDataSource newsDataSource;

@NonNull
@Override
public DataSource<Integer, NewsModel> create() {
    newsDataSource = new NewsDataSource();
    newsDataSourceMutableLiveData=new MutableLiveData<>();
    newsDataSourceMutableLiveData.postValue(newsDataSource);
    return newsDataSource;
}

public MutableLiveData<NewsDataSource> getNewsDataSourceMutableLiveData() {
    return newsDataSourceMutableLiveData;
}
}

追溯API.java

public interface RetroApi {
    @GET("top-headlines")
    Single<Response> getAllNews(@Query("page") int page,
                                @Query("pageSize") int pageSize,
                                @Query("country") String country,
                                @Query("apiKey") String apiKey,
                                @Query("category")String category);
}

追溯服务.java

public class RetroService {

private static OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
        .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
        .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
        .retryOnConnectionFailure(false)
        .build();

private static RetroApi api;

private static RetroService instance;

public static RetroService getInstance(){
    if(instance == null){
        instance=new RetroService();
    }
    return instance;
}

private RetroService() {
    api = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
            .build()
            .create(RetroApi.class);
}
public Single<Response> getData(int page,int pageSize,String country,String key,String category){
    return api.getAllNews(page,pageSize,country,key,category);
}
}

新闻适配器.java

public class NewsAdapter extends PagedListAdapter<NewsModel,NewsAdapter.NewsViewHolder>  {

private Context context;
private List<NewsModel> mNews;

private static final DiffUtil.ItemCallback<NewsModel> NEWS_COMPARATOR=new DiffUtil.ItemCallback<NewsModel>() {
    @Override
    public boolean areItemsTheSame(@NonNull NewsModel oldItem, @NonNull NewsModel newItem) {
        return oldItem.getTitle() == newItem.getTitle();
    }

    @SuppressLint("DiffUtilEquals")
    @Override
    public boolean areContentsTheSame(@NonNull NewsModel oldItem, @NonNull NewsModel newItem) {
        return oldItem.equals(newItem);
    }
};

public NewsAdapter(Context context) {
    super(NEWS_COMPARATOR);
    this.context=context;
}

@NonNull
@Override
public NewsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 LayoutInflater mInflater= LayoutInflater.from(parent.getContext());
    NewsItemBinding binding=DataBindingUtil.inflate(mInflater,R.layout.news_item,parent,false);
    return new NewsViewHolder(binding);
}

@Override
public void onBindViewHolder(@NonNull NewsViewHolder holder, int position) {
    holder.bindData(getItem(position));
    holder.binding.setClickListener(news -> {
        setupBottomSheetDialog(news);
    });
}

private void setupBottomSheetDialog(NewsModel mNew) {
    LayoutBottomSheetBinding binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.layout_bottom_sheet, null, false);
    BottomSheetDialog dialogBox=new BottomSheetDialog(context);
    View v=binding.getRoot();
    dialogBox.setContentView(v);
    binding.setMNew(mNew);
    dialogBox.show();
}

class NewsViewHolder extends RecyclerView.ViewHolder{

    NewsItemBinding binding;

    public NewsViewHolder(@NonNull NewsItemBinding binding) {
        super(binding.getRoot());
        this.binding=binding;

    }
    public void bindData(NewsModel model){
        binding.setMNew(model);
        binding.executePendingBindings();
    }
}
}
d8tt03nd

d8tt03nd1#

我解决了我的问题,但我不建议这样做。我认为可能有更好的解决办法。所以如果你有更好的解决办法请告诉我。这是我的解决办法。首先我补充道 public MutableLiveData<String> categoryLiveData=new MutableLiveData<>(); 到我的mainactivityviewmodel类ı 将init()方法更改为

public void init(String category) {
    NewsDataSourceFactory newsFactory=new NewsDataSourceFactory(category);
    liveDataSource=newsFactory.getNewsDataSourceMutableLiveData();
    PagedList.Config config=new PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setPageSize(PAGE_SIZE)
            .build();
    newsPagedList=new LivePagedListBuilder<>(newsFactory,config).build();
}

我把这些线加到我的主要活动中去观察分类数据,然后在里面 onOptionsItemSelected() 将选定值赋给categorylivedata。
主要活动

mViewModel.categoryLiveData.postValue(categoryTv.getText().toString().toLowerCase());
    mViewModel.categoryLiveData.observe(mActivity, s -> {
        mViewModel.init(s);           
        observeViewModel();
    });
selectBtn.setOnClickListener(v -> {
            categoryTv.setText(categoryArray[np.getValue()]);
            mViewModel.categoryLiveData.postValue(categoryTv.getText().toString().toLowerCase());
            d.dismiss();
        });

我用category参数向newsdatasourcefactory添加了一个构造函数。

public NewsDataSourceFactory(String category) {
    newsDataSource = new NewsDataSource(category);
}

最后在newsdatasource中创建了一个构造函数,并将category作为参数传递。

private String category;
public NewsDataSource(String category){
    this.category=category;
}

并将该类别传递给我的请求方法。

mResponse = service.getData(FIRST_PAGE, PAGE_SIZE, "us", API_KEY,category);

相关问题