英文:
Android studio, recycle view
问题
以下是您提供的代码的翻译部分:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
private Context context;
private List<WorkDayItem> workDayItemList;
// 构造函数
public RecyclerViewAdapter(Context context, List<WorkDayItem> workDayItemList) {
this.context = context;
this.workDayItemList = workDayItemList;
}
// 创建ViewHolder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemWorkDay = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_one_work_day, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(itemWorkDay);
return myViewHolder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called." + (position + 1) + "\n" + workDayItemList.get(position).toString());
final WorkDayItem workDayItem = workDayItemList.get(position);
String dateStart = DateFormat.format("dd.MM", workDayItem.getDateStart()).toString();
String timeStart = DateFormat.format("HH:mm", workDayItem.getDateStart()).toString();
String timeEnd = DateFormat.format("HH:mm", workDayItem.getDateEnd()).toString();
// 从Firebase的字符串格式转换为小时和分钟的整数格式
Double convertingDataFromFirebase;
try {
convertingDataFromFirebase = Double.parseDouble(new DecimalFormat("##.##").format(workDayItem.getCount_hours()));
} catch (NumberFormatException e) {
convertingDataFromFirebase = 0.0;
}
int hours = convertingDataFromFirebase.intValue();
convertingDataFromFirebase = (convertingDataFromFirebase - convertingDataFromFirebase.intValue()) * 60;
int minutes = convertingDataFromFirebase.intValue();
// 检查当前项目是否有描述
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: desc dot added");
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
holder.dayPosition.setText((position + 1) + "");
holder.dateStart.setText(dateStart);
holder.timeStart.setText(timeStart);
holder.timeEnd.setText(timeEnd);
holder.countOfHours.setText(hours + ":" + minutes);
// 点击当前项时打开带有一些功能的警报对话框
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
initializeAlertDialogForItem(workDayItem, holder);
}
});
}
// 初始化关于当前工作日的数据,并有一个按钮用于更改信息
private void initializeAlertDialogForItem(final WorkDayItem workDayItem, final MyViewHolder holder) {
// 初始化警报对话框
final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
View itemWork = LayoutInflater.from(context).inflate(R.layout.ad_item_desc, null, false);
alertDialog.setView(itemWork);
alertDialog.show();
// 初始化警报对话框的按钮和视图
final ImageButton change = alertDialog.findViewById(R.id.itemAD_Edit);
final ImageButton delete = alertDialog.findViewById(R.id.itemAD_Delete);
TextView description = alertDialog.findViewById(R.id.itemADDescription);
TextView date = alertDialog.findViewById(R.id.itemADDate);
TextView from = alertDialog.findViewById(R.id.itemADFrom);
TextView to = alertDialog.findViewById(R.id.itemADTO);
String timeStart = DateFormat.format("HH:mm", workDayItem.getDateStart()).toString();
String timeEnd = DateFormat.format("HH:mm", workDayItem.getDateEnd()).toString();
String dateStart = DateFormat.format("dd.MM.yyyy", workDayItem.getDateStart()).toString();
date.setText(dateStart);
from.setText(timeStart);
to.setText(timeEnd);
description.setText(workDayItem.getDesc());
// 更改按钮
change.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onClick(View v) {
AlertDialogReport userReport = new AlertDialogReport(context, "replace-remove", workDayItem);
userReport.initializeAlertDialog();
alertDialog.dismiss();
}
});
delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 从Firebase中删除数据
// ...
// 从Sqlite数据库中删除数据
// ...
alertDialog.dismiss();
Toast.makeText(context, R.string.item_deleted, Toast.LENGTH_SHORT).show();
holder.parentLayout.removeAllViews();
}
});
}
// 获取项目数目
@Override
public int getItemCount() {
return workDayItemList.size();
}
// ViewHolder类
public class MyViewHolder extends RecyclerView.ViewHolder {
private LinearLayout parentLayout;
private TextView doteOfDesc, dayPosition, dateStart, timeStart, timeEnd, countOfHours;
public MyViewHolder(View view) {
super(view);
doteOfDesc = view.findViewById(R.id.itemDote);
dayPosition = view.findViewById(R.id.itemDayPosition);
dateStart = view.findViewById(R.id.itemDateStart);
timeStart = view.findViewById(R.id.itemStartHour);
timeEnd = view.findViewById(R.id.itemEndHour);
countOfHours = view.findViewById(R.id.itemCountOfHours);
parentLayout = view.findViewById(R.id.itemWorkDay);
}
}
}
请注意,这个翻译只包括了您提供的代码部分。如果您有任何其他问题或需要进一步帮助,请随时提问。
英文:
I have some error in android studio.
When i try to add symbol ('*') to special item, it also add the symbol to the item that placed in +14 from the first.
I will glad if someone have solution for this problem.
For more information you can check this link, where i describe the problem.
https://youtu.be/CJFkt-Cck1A
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-none -->
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
private Context context;
private List<WorkDayItem> workDayItemList;
//Complete
public RecyclerViewAdapter(Context context, List<WorkDayItem> workDayItemList) {
this.context = context;
this.workDayItemList = workDayItemList;
}
//Complete
//Here we create view- itemWorkday and inflate it by layout- item_one_work_day
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemWorkDay = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_one_work_day, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(itemWorkDay);
return myViewHolder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called." + (position + 1) + "\n" + workDayItemList.get(position).toString());
final WorkDayItem workDayItem = workDayItemList.get(position);
String dateStart = (String) DateFormat.format("dd.MM", workDayItem.getDateStart());
String timeStart = (String) DateFormat.format("HH:mm", workDayItem.getDateStart());
String timeEnd = (String) DateFormat.format("HH:mm", workDayItem.getDateEnd());
//Convert data from firebase String format to int hours and minutes format.
Double convertingDataFromFirebase;
try {
convertingDataFromFirebase = Double.parseDouble(new DecimalFormat("##.##").format(workDayItem.getCount_hours()));
} catch (NumberFormatException e) {
convertingDataFromFirebase = 0.0;
}
int hours = convertingDataFromFirebase.intValue();
convertingDataFromFirebase = (convertingDataFromFirebase - convertingDataFromFirebase.intValue()) * 60;
int minutes = convertingDataFromFirebase.intValue();
//Check if current item have description
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: desc dote added");
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
holder.dayPosition.setText((position + 1) + "");
holder.dateStart.setText(dateStart);
holder.timeStart.setText(timeStart);
holder.timeEnd.setText(timeEnd);
holder.countOfHours.setText(hours + ":" + minutes);
//On click on current hold open alert dialog with some functions
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
initializeAlertDialogForItem(workDayItem, holder);
}
});
}
//initialize data about current work day and have button for changing information
private void initializeAlertDialogForItem(final WorkDayItem workDayItem, final MyViewHolder holder) {
//Initialize alert dialog
final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
View itemWork = LayoutInflater.from(context)
.inflate(R.layout.ad_item_desc, null, false);
alertDialog.setView(itemWork);
alertDialog.show();
//initialize alert dialog buttons and views
final ImageButton change = alertDialog.findViewById(R.id.itemAD_Edit);
final ImageButton delete = alertDialog.findViewById(R.id.itemAD_Delete);
TextView description = alertDialog.findViewById(R.id.itemADDescription);
TextView date = alertDialog.findViewById(R.id.itemADDate);
TextView from = alertDialog.findViewById(R.id.itemADFrom);
TextView to = alertDialog.findViewById(R.id.itemADTO);
String timeStart = (String) (DateFormat.format("HH:mm", workDayItem.getDateStart()));
String timeEnd = (String) (DateFormat.format("HH:mm", workDayItem.getDateEnd()));
String dateStart = (String) (DateFormat.format("dd.MM.yyyy", workDayItem.getDateStart()));
date.setText(dateStart);
from.setText(timeStart);
to.setText(timeEnd);
description.setText(workDayItem.getDesc());
//Change button
change.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onClick(View v) {
AlertDialogReport userReport = new AlertDialogReport(context, "replace-remove", workDayItem);
userReport.initializeAlertDialog();
alertDialog.dismiss();
}
});
delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Delete data from firebase
Login.fc.databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String itemTime = "" + workDayItem.getDateStart().getTime();
String firebaseTime = "" + snapshot.child("dateStart").child("time").getValue();
if (itemTime.equals(firebaseTime)) {
Login.fc.databaseReference.child(snapshot.getKey()).removeValue();
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
//Delete data from SqLiteDatabase
MySQLDataBase dataBase = new MySQLDataBase(context);
dataBase.deleteItem(workDayItem);
//Finish with alert dialog and notify user
alertDialog.dismiss();
Toast.makeText(context, R.string.item_deleted, Toast.LENGTH_SHORT).show();
holder.parentLayout.removeAllViews();
}
});
}
//Complete
@Override
public int getItemCount() {
return workDayItemList.size();
}
//Complete
//Here we catch our view and getting reference between view and our objects
public class MyViewHolder extends RecyclerView.ViewHolder {
private LinearLayout parentLayout;
private TextView doteOfDesc, dayPosition, dateStart, timeStart, timeEnd, countOfHours;
public MyViewHolder(View view) {
super(view);
doteOfDesc = view.findViewById(R.id.itemDote);
dayPosition = view.findViewById(R.id.itemDayPosition);
dateStart = view.findViewById(R.id.itemDateStart);
timeStart = view.findViewById(R.id.itemStartHour);
timeEnd = view.findViewById(R.id.itemEndHour);
countOfHours = view.findViewById(R.id.itemCountOfHours);
parentLayout = view.findViewById(R.id.itemWorkDay);
}
}
}
<!-- end snippet -->
答案1
得分: 3
请尝试添加以下内容:
//检查当前项目是否有描述
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: 描述点已添加");
holder.doteOfDesc.setVisibility(View.VISIBLE);
} else if (workDayItemList.get(position).getDesc().length() < 2
&& holder.doteOfDesc.getVisibility() == View.VISIBLE) {
holder.doteOfDesc.setVisibility(View.GONE);
}
发生这种情况的原因是,RecyclerView
会创建足够多的ViewHolders
以覆盖整个屏幕以及一些额外的(在您的情况下为12个),然后通过重新绑定视图来重用它们。您在第2个ViewHolder
中将doteOfDesc
设置为View.VISIBLE
,但从未将其设置回View.GONE
,这就是为什么每次重用ViewHolder
时都会使doteOfDesc
可见的原因。
更美观的版本:
Boolean hasDescription = workDayItemList.get(position).getDesc().length() > 2;
holder.doteOfDesc.setVisibility(hasDescription ? View.VISIBLE : View.GONE);
英文:
Try adding this:
//Check if current item have description
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: desc dote added");
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
else if( workDayItemList.get(position).getDesc().length() < 2
&& holder.doteOfDesc.getVisibility()== View.VISIBLE ){
holder.doteOfDesc.setVisibility(View.GONE);
}
The reason why this is happening is that RecyclerView
creates as many ViewHolders
as its needed to cover a whole screen plus few extra ( 12 in your case) then reuses them via rebinding values to views. And you set doteOfDesc
to View.VISIBLE
in 2. ViewHolder
, but never set it back to View.GONE
, thats why every time that ViewHolder
is reused it will have doteOfDesc
visible.
The Prettier version:
Boolean hasDescription = workDayItemList.get(position).getDesc().length() > 2;
holder.doteOfDesc.setVisibility( hasDescription ? View.VISIBLE : View.GONE);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论