EDIT2 :我在holder.showTaskRecyclerView
为false
隐藏视图的情况下明确说明,以便明确涵盖true
和{{ 1}} false
中的案例。我仍然有同样的问题。
EDIT1:我应该补充一点,如果我使用onBindViewHolder
代替tasksRecyclerView
,notifyDataSetChanged()
的显示和隐藏效果会很好,但这会禁用动画而且成本更高。
我的ViewHolder中有一个名为notifyItemChanged()
的RecyclerView,只要单击该视图,就会显示和隐藏它。 (这是主要的RecyclerView里面的RecyclerView,所以说。):
tasksRecyclerView
目前,代码中的onClick设置为切换ViewHolder中定义的变量( public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView routineStateImgView;
public TextView alarmTextView;
public TextView routineNameTextView;
public RecyclerView tasksRecyclerView;
public boolean showTaskRecyclerView = false;
public ViewHolder(View routineItemView){
super(routineItemView);
routineItemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//toggle showing TaskRecyclerView
showTaskRecyclerView = !showTaskRecyclerView;
notifyItemChanged(getAdapterPosition());
}
});
routineStateImgView = (ImageView) routineItemView.findViewById(R.id.routineStateImgView);
alarmTextView = (TextView) routineItemView.findViewById(R.id.alarmTextView);
routineNameTextView = (TextView) routineItemView.findViewById(R.id.routineNameTextView);
tasksRecyclerView = (RecyclerView) routineItemView.findViewById(R.id.tasksRecyclerView);
}
public ImageView getRoutineStateImgView() {
return routineStateImgView;
}
public TextView getAlarmTextView(){
return alarmTextView;
}
public TextView getRoutineNameTextView(){
return routineNameTextView;
}
public RecyclerView getTasksRecyclerView(){
return tasksRecyclerView;
}
}
),然后调用showTaskRecyclerView
以动画更新项目更改。
当调用OnBindViewHolder时,它会再次检查切换变量(notifyItemChanged(getAdapterPosition())
)的状态,并根据变量隐藏或取消隐藏RecyclerView。您可以在此代码段中的Log.d方法行之后的代码中看到此逻辑:
showTaskRecyclerView
我希望每次点击都会看到RecyclerView隐藏或取消隐藏。但是,我每2次点击后才会看到隐藏/取消隐藏行为。
点击5次后,这是Log.d的输出:
public void onBindViewHolder(RoutinesRecyclerViewAdapter.ViewHolder holder, int position) {
//Replace contents of view with data from item in adapterRoutinesList at position.
Routine routine = adapterRoutinesList.get(position);
TasksRecyclerViewAdapter mTasksRecyclerViewAdapter = null;
if(routine == null){
holder.getRoutineStateImgView().setImageResource(android.R.color.transparent);
holder.getAlarmTextView().setText("");
holder.getRoutineNameTextView().setText("");
holder.getTasksRecyclerView().setVisibility(View.GONE);
}else{
DateFormat dayTimeFormat = new SimpleDateFormat("HH:mm", Locale.US);
String dayTimeString = dayTimeFormat.format(routine.getWakeupTime().getTime());
holder.getAlarmTextView().setText(dayTimeString);
holder.getRoutineNameTextView().setText(routine.getName());
if(routine.getEnableRoutine()) {
holder.getRoutineStateImgView().setImageResource(R.drawable.check_mark);
}
else{
holder.getRoutineStateImgView().setImageResource(R.drawable.x_mark);
}
Log.d(TAG, "position: " + position + " holder: " + holder + " show?: " + holder.showTaskRecyclerView);
if(holder.showTaskRecyclerView) {
TasksManager mTasksManager = adapterTasksListCache.get(routine.getId());
if (mTasksManager == null) {
mTasksManager = new TasksManager(routine.getId());
mTasksManager.readTasksFromDisk(mContext);
adapterTasksListCache.put(routine.getId(), mTasksManager);
}
mTasksRecyclerViewAdapter = adapterTasksViewCache.get(routine.getId());
if (mTasksRecyclerViewAdapter == null) {
mTasksRecyclerViewAdapter = new TasksRecyclerViewAdapter(
mContext,
position,
mTasksManager.getTasksListFromCache(),
mRequestImageCaptureCallBack,
mTaskEditTextListener);
adapterTasksViewCache.put(routine.getId(), mTasksRecyclerViewAdapter);
}
RecyclerView.LayoutManager mTaskLayoutManager = new LinearLayoutManager(mContext);
holder.getTasksRecyclerView().setLayoutManager(mTaskLayoutManager);
holder.getTasksRecyclerView().setAdapter(mTasksRecyclerViewAdapter);
holder.getTasksRecyclerView().setHasFixedSize(true);
holder.getTasksRecyclerView().setVisibility(View.VISIBLE);
}
else{
holder.getTasksRecyclerView().setVisibility(View.GONE);
}
}
}
我的解释是使用notifyItemChanged提示使用相同ViewHolder的2个副本用于过渡动画目的(一个具有旧视图状态,一个具有新状态)。但是,旧副本中的变量副本错误地更改。我假设我对notifyItemChanged如何工作有错误的理解,所以我来这里寻求帮助:/
此外,当我点击非常快时,我不知道是什么原因引起了这个问题:如果我点击得足够快(大约快到不到半秒),我看不出任何变化。
logcat显示以下内容:
04-16 21:33:37.026 13522-13522/co.edu.javeriana.faros D/RoutinesViewAdapter: position: 0 holder: ViewHolder{263b1503 position=0 id=-1, oldPos=-1, pLpos:-1 no parent} show?: false
04-16 21:33:42.626 13522-13522/co.edu.javeriana.faros D/RoutinesViewAdapter: position: 0 holder: ViewHolder{883eb98 position=0 id=-1, oldPos=-1, pLpos:-1 no parent} show?: false
04-16 21:33:44.511 13522-13522/co.edu.javeriana.faros D/RoutinesViewAdapter: position: 0 holder: ViewHolder{263b1503 position=0 id=-1, oldPos=-1, pLpos:-1 no parent} show?: true
04-16 21:33:46.274 13522-13522/co.edu.javeriana.faros D/RoutinesViewAdapter: position: 0 holder: ViewHolder{883eb98 position=0 id=-1, oldPos=-1, pLpos:-1 no parent} show?: true
04-16 21:33:47.938 13522-13522/co.edu.javeriana.faros D/RoutinesViewAdapter: position: 0 holder: ViewHolder{263b1503 position=0 id=-1, oldPos=-1, pLpos:-1 no parent} show?: false
04-16 21:41:52.756 13522-13522/co.edu.javeriana.faros D/RoutinesViewAdapter: position: 0 holder: ViewHolder{883eb98 position=0 id=-1, oldPos=-1, pLpos:-1 no parent} show?: false
有什么想法吗?
答案 0 :(得分:0)
当holder.showTaskRecyclerView
为false
时,您需要实现条件的逻辑。
View
维持其状态,因此您必须明确修改它们。放置一些逻辑来隐藏它并检查它是否有效。
答案 1 :(得分:0)
我通过在ListArray
之外为ViewHolder
定义showTaskRecyclerView
并为适配器中的每个项目ViewHolder
来解决此问题。
通过这种方式,新旧showTaskRecyclerView
每个项目都会看到相同的单showTaskRecyclerView
,而ViewHolder
中每个项目的new_dict = {datetime.strptime(key, "%Y-%m-%d %H:%M:%S"): val for key, val in alerts['alert_date'].items()}
不会同步datetime.strptime