Sea*_*Lab 5 java android android-recyclerview
我将 3 部分数据显示在其中RecyclerView:
storyListyukulListhomeList当我尝试仅显示storyList或中yukulList的homeList数据时RecyclerView,它有效。但是当我尝试显示多个数据时,例如:storyList && yukulListor storyList && yukulList && homeList,它会显示
java.lang.IndexOutOfBoundsException。
我尝试过添加notifyDataSetChanged(),但无法成功。
显示收藏夹列表.java
public class ShowFavouriteList extends AppCompatActivity implements AdapterFavList.FavListener {
private RecyclerView recyclerView;
private TextView noFavtsTV;
AppPreferences appPreferences;
private SearchView searchView;
private AdapterFavList yAdapterFavlist;
private AdapterFavList mAdapterFavlist;
private AdapterFavList tAdapterFavlist;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_favourite_list);
SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
finish();
startActivity(getIntent());
}
});
//toolbar logo and desc
Toolbar topToolBar = (Toolbar) findViewById(R.id.toolbarTidur);
setSupportActionBar(topToolBar); //munculkan menu ke toolbar
getSupportActionBar().setDisplayHomeAsUpEnabled(true); //this line shows back button
recyclerView = findViewById(R.id.recycler_view);
noFavtsTV = findViewById(R.id.no_favt_text);
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("MyPref", 0);
SharedPreferences sPTuru = getApplicationContext().getSharedPreferences("MyTuru", 0);
SharedPreferences sPHome = getApplicationContext().getSharedPreferences("MyHome", 0);
PreferenceMenejer preferenceMenejer = new PreferenceMenejer(sharedPreferences, sPTuru, sPHome);
appPreferences = new AppPreferences(preferenceMenejer);
fetchData();
} // Oncreate
private void fetchData() {
List<Story> storyList = appPreferences.getFavouriteCardList();
List<YukulModel> yukulList = appPreferences.getFavouriteYukul();
List<HomeModel> homeList = appPreferences.getFavouriteHome();
if(storyList != null && storyList.size() > 0) {
showNoFavtText(false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
tAdapterFavlist = new AdapterFavList(this, storyList, yukulList, homeList, this, appPreferences);
recyclerView.setAdapter(tAdapterFavlist);
tAdapterFavlist.notifyDataSetChanged();
}
if(yukulList != null && yukulList.size() > 0) {
showNoFavtText(false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
yAdapterFavlist = new AdapterFavList(this, storyList, yukulList, homeList, this, appPreferences);
recyclerView.setAdapter(yAdapterFavlist);
yAdapterFavlist.notifyDataSetChanged();
}
if(homeList != null && homeList.size() > 0) {
showNoFavtText(false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
mAdapterFavlist = new AdapterFavList(this, storyList, yukulList, homeList, this, appPreferences);
recyclerView.setAdapter(mAdapterFavlist);
mAdapterFavlist.notifyDataSetChanged();
}
}
@Override
public void onItemKlik(RecyclerView.ViewHolder viewHolder, HomeModel modelField, int position) {
// Tidur List
List<HomeModel> modelList = appPreferences.getFavouriteHome();
HomeModel click = modelList.get(position);
Toast.makeText(getApplicationContext(), "Selected: " + click.getName(), Toast.LENGTH_LONG).show();
int id = Integer.parseInt(click.getIdStory());
if (id == 0) {
startActivity(new Intent(this, DoaPagi.class));
} else if (id == 1) {
startActivity(new Intent(this, DoaSore.class));
} else if (id == 2) {
startActivity(new Intent(this, DoaWc.class));
} else if (id == 3) {
startActivity(new Intent(this, DoaMasjid.class));
} else if (id == 4) {
startActivity(new Intent(this, DzikirShalat.class));
} else if (id == 5) {
startActivity(new Intent(this, ChildYukul.class));
} else if (id == 6) {
startActivity(new Intent(this, DoaPakaian.class));
} else if (id == 7) {
startActivity(new Intent(this, ChildTidur.class));
}
}
@Override
public void onItemTuru(RecyclerView.ViewHolder viewHolder, Story tField, int position) {
// Tidur List
List<Story> storyList = appPreferences.getFavouriteCardList();
Story clic = storyList.get(position);
int idTuru = Integer.parseInt(clic.getIdStory());
if (idTuru == 0) {
startActivity(new Intent(this, DoaMauTidur.class));
} else if (idTuru == 1) {
startActivity(new Intent(this, DoaBangunt.class));
} else if (idTuru == 2) {
startActivity(new Intent(this, DoaJimak.class));
}
}
@Override
public void onItemYukul(RecyclerView.ViewHolder viewHolder, YukulModel yField, int position) {
// Tidur List
}
private void showNoFavtText(boolean show) {
noFavtsTV.setVisibility(show ? View.VISIBLE : View.GONE); //jika data yang ditampilkan tidak ada, maka show noFavsTv
recyclerView.setVisibility(show ? View.GONE : View.VISIBLE); //jika data yang ditampilkan tidak ada, maka don't show rV
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_fav, menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
// Associate searchable_tidur configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search_fav).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
// listening to search query text change
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// filter recycler view when query submitted
mAdapterFavlist.getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String query) {
// filter recycler view when text is changed
mAdapterFavlist.getFilter().filter(query);
return false;
}
});
return true;
}
// Agar back button pada halaman induk settings berfungsi
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.search_fav) {
return true;
}
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Run Code Online (Sandbox Code Playgroud)
AdapterFavList.java
public class AdapterFavList extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
public static final String ACTION_LIKE_IMAGE_CLICKED = "action_like_image_button";
final int VIEW_TYPE_TIDUR = 0;
final int VIEW_TYPE_YUKUL = 1;
final int VIEW_TYPE_HOME = 2;
private Context context;
private AppPreferences appPreferences;
private List<Story> storyList;
private List<YukulModel> yukulList;
private List<HomeModel> homeList;
private List<HomeModel> homeListFiltered;
private List<Object> collection = new ArrayList<Object>();
private FavListener listener;
private int changedItemPosition;
private boolean isLiked;
public AdapterFavList(Context context, List<Story> storyList, List<YukulModel> yukulList, List<HomeModel> homeList, FavListener listener, AppPreferences appPreferences) {
this.context = context;
this.storyList = storyList;
this.yukulList = yukulList;
this.homeListFiltered = homeList;
this.listener = listener;
this.appPreferences = appPreferences;
addData();
}
public void addData() {
storyList = appPreferences.getFavouriteCardList();
yukulList = appPreferences.getFavouriteYukul();
homeList = appPreferences.getFavouriteHome();
if(storyList != null && storyList.size() > 0) {
collection.addAll(storyList);
}
if(yukulList != null && yukulList.size() > 0) {
collection.addAll(yukulList);
}
if(homeList != null && homeList.size() > 0) {
collection.addAll(homeListFiltered);
}
}
public interface FavListener {
void onItemKlik(RecyclerView.ViewHolder viewHolder, HomeModel modelField, int position);
void onItemTuru(RecyclerView.ViewHolder viewHolder, Story tField, int position);
void onItemYukul(RecyclerView.ViewHolder viewHolder, YukulModel yField, int position);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if(viewType == VIEW_TYPE_TIDUR) {
return new tidurViewHolder(LayoutInflater.from(context).inflate(R.layout.item_story_favourite_list, parent, false));
}
if(viewType == VIEW_TYPE_YUKUL) {
return new yukulViewHolder(LayoutInflater.from(context).inflate(R.layout.item_favourite_yukul, parent, false));
}
if(viewType == VIEW_TYPE_HOME) {
return new homeViewHolder(LayoutInflater.from(context).inflate(R.layout.item_fav_home, parent, false));
}
return null;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Object item = collection.get(position);
if(holder instanceof tidurViewHolder){
((tidurViewHolder) holder).bind(storyList.get(position));
((tidurViewHolder) holder).setViewData((Story) item, holder.getAdapterPosition());
}
if(holder instanceof yukulViewHolder){
((yukulViewHolder) holder).bind(yukulList.get(position));
((yukulViewHolder) holder).viewDataYukul((YukulModel) item, holder.getAdapterPosition());
}
if(holder instanceof homeViewHolder){
((homeViewHolder) holder).bind(homeList.get(position));
((homeViewHolder) holder).viewDataHome((HomeModel) item, holder.getAdapterPosition());
}
}
@Override
public int getItemCount() {
return collection.size();
}
@Override
public int getItemViewType(int position){
Object item = collection.get(position);
if(item instanceof Story) {
return VIEW_TYPE_TIDUR;
}
if(item instanceof YukulModel){
return VIEW_TYPE_YUKUL;
}
if(item instanceof HomeModel){
return VIEW_TYPE_HOME;
}
return -1;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
List<HomeModel> homeList = appPreferences.getFavouriteHome();
if (charString.isEmpty()) {
homeListFiltered = homeList;
}
else {
List<HomeModel> filteredList = new ArrayList<>();
for (HomeModel row : homeList) {
if ( row.getName().toLowerCase().contains(charString.toLowerCase()) ) {
filteredList.add(row);
}
}
homeListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = homeListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
homeListFiltered = (ArrayList<HomeModel>) filterResults.values;
notifyDataSetChanged();
}
};
} //Filter
public void tidurPutHeart(boolean isChecked, Story tidurstory) {
SharedPreferences tidursharedPreferences = context.getSharedPreferences("Turu", Activity.MODE_PRIVATE);
SharedPreferences.Editor tidureditor = tidursharedPreferences.edit();
tidureditor.putBoolean(tidurstory.getIdStory(), isChecked);
tidureditor.commit();
}
public void yukulPutHeart(boolean isChecked, YukulModel yukulstory) {
SharedPreferences yukulsharedPreferences = context.getSharedPreferences("Yukul", Activity.MODE_PRIVATE);
SharedPreferences.Editor yukuleditor = yukulsharedPreferences.edit();
yukuleditor.putBoolean(yukulstory.getIdStory(), isChecked);
yukuleditor.commit();
}
public void homePutHeart(boolean isChecked, HomeModel homestory) {
SharedPreferences homesharedPreferences = context.getSharedPreferences("Home", Activity.MODE_PRIVATE);
SharedPreferences.Editor homeeditor = homesharedPreferences.edit();
homeeditor.putBoolean(homestory.getIdStory(), isChecked);
homeeditor.commit();
}
//ViewHolder
public class tidurViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private CheckBox likeCheckBox;
public tidurViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_view);
likeCheckBox = itemView.findViewById(R.id.like_button_cb);
} // itemView
public void bind(final Story item) {
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onItemTuru(tidurViewHolder.this, item, position);
}
}
}
});
}
public void setViewData(final Story story, final int adapterPosition) {
textView.setText(story.getName());
if (story.getIsLiked() == 1) {
likeCheckBox.setChecked(false);
}
else {
likeCheckBox.setChecked(true);
}
likeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
changedItemPosition = adapterPosition;
if (buttonView.isPressed()) {
if (isChecked) {
tidurPutHeart(isChecked, story);
appPreferences.saveFavouriteCard(story);
}
else {
isLiked = false;
tidurPutHeart(isChecked, story);
appPreferences.deleteCard(story.getIdStory());
// updateLikes();
Toast.makeText(context, "Removed", Toast.LENGTH_SHORT).show();
if(collection.size() == 0) {
((Activity)context).finish();
context.startActivity(((Activity) context).getIntent());
}
}
}
}
});
} //setviewdata
public void updateLikes() {
if (!isLiked && storyList.get(changedItemPosition).getIsLiked() == 0) { //jika like dicabut (pada posisi hati yang sedang merah) di halaman favourite list
storyList.get(changedItemPosition).setIsLiked(0); //maka cabut juga warna merah di halaman favourite list
notifyItemRangeChanged(getAdapterPosition(), collection.size());
collection.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
}
} //updateLikes
} //tidurViewholder
//homeViewHolder
public class homeViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private CheckBox likeCheckBox;
public homeViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_view);
likeCheckBox = itemView.findViewById(R.id.like_button_cb);
} // itemView
public void bind(final HomeModel item) {
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onItemKlik(homeViewHolder.this, item, position);
}
}
}
});
}
public void viewDataHome(final HomeModel story, final int adapterPosition) {
textView.setText(story.getName());
if (story.getIsLiked() == 1) {
likeCheckBox.setChecked(false);
}
else {
likeCheckBox.setChecked(true);
}
likeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
changedItemPosition = adapterPosition;
if (buttonView.isPressed()) {
if (isChecked) {
homePutHeart(isChecked, story);
appPreferences.saveFavouriteHome(story);
}
else {
isLiked = false;
homePutHeart(isChecked, story);
appPreferences.deleteCardHome(story.getIdStory());
在您的适配器中,该collection列表是唯一可以使用 安全访问的列表position。尝试调用yukulList.get(position)保证最终会抛出异常。
所有这些行onBindViewHolder()都是不安全的,应该更改:
Run Code Online (Sandbox Code Playgroud)@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { // ... ((tidurViewHolder) holder).bind(storyList.get(position)); // ... ((yukulViewHolder) holder).bind(yukulList.get(position)); // ... ((homeViewHolder) holder).bind(homeList.get(position)); // ... }
getItemViewType()您可以访问通过调用返回的“视图类型”值holder.getItemViewType(),并且可以使用该值来确定要使用的视图持有者和项目的正确类型:
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Object item = collection.get(position);
int adapterPosition = holder.getAdapterPosition();
if (holder.getItemViewType() == VIEW_TYPE_TIDUR){
Story story = (Story) item;
tidurViewHolder vh = (tidurViewHolder) holder;
vh.bind(story);
vh.setViewData(story, adapterPosition);
} else if (holder.getItemViewType() == VIEW_TYPE_YUKUL){
YukulModel yukul = (YukulModel) item;
yukulViewHolder vh = (yukulViewHolder) holder;
vh.bind(yukul);
vh.viewDataYukul(yukul, adapterPosition);
} else if (holder.getItemViewType() == VIEW_TYPE_HOME){
HomeModel home = (HomeModel) item;
homeViewHolder vh = (homeViewHolder) holder;
vh.bind(home);
vh.viewDataHome(home, adapterPosition);
}
}
Run Code Online (Sandbox Code Playgroud)
另请注意,无需实际传递holder.getAdapterPosition()到 eg setViewData(),因为您可以简单地getAdapterPosition()从tidurViewHolder方法内调用。
我还想说,您可以将您的bind()和setViewData()调用合并为一个,这将使您得到以下结果:
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Object item = collection.get(position);
if (holder.getItemViewType() == VIEW_TYPE_TIDUR){
((tidurViewHolder) holder).bind((Story) item);
} else if (holder.getItemViewType() == VIEW_TYPE_YUKUL){
((yukulViewHolder) holder).bind((YukulModel) item);
} else if (holder.getItemViewType() == VIEW_TYPE_HOME){
((homeViewHolder) holder).bind((HomeModel) item);
}
}
Run Code Online (Sandbox Code Playgroud)