Sure, here’s the translation: 安卓工作室,回收视图

huangapple go评论78阅读模式
英文:

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&lt;RecyclerViewAdapter.MyViewHolder&gt; {
private static final String TAG = &quot;RecyclerViewAdapter&quot;;
private Context context;
private List&lt;WorkDayItem&gt; workDayItemList;
//Complete
public RecyclerViewAdapter(Context context, List&lt;WorkDayItem&gt; 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, &quot;onBindViewHolder: called.&quot; + (position + 1) + &quot;\n&quot; + workDayItemList.get(position).toString());
final WorkDayItem workDayItem = workDayItemList.get(position);
String dateStart = (String) DateFormat.format(&quot;dd.MM&quot;, workDayItem.getDateStart());
String timeStart = (String) DateFormat.format(&quot;HH:mm&quot;, workDayItem.getDateStart());
String timeEnd = (String) DateFormat.format(&quot;HH:mm&quot;, workDayItem.getDateEnd());
//Convert data from firebase String format to int hours and minutes format.
Double convertingDataFromFirebase;
try {
convertingDataFromFirebase = Double.parseDouble(new DecimalFormat(&quot;##.##&quot;).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() &gt; 2) {
Log.i(TAG, &quot;TESTER: desc dote added&quot;);
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
holder.dayPosition.setText((position + 1) + &quot;&quot;);
holder.dateStart.setText(dateStart);
holder.timeStart.setText(timeStart);
holder.timeEnd.setText(timeEnd);
holder.countOfHours.setText(hours + &quot;:&quot; + 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(&quot;HH:mm&quot;, workDayItem.getDateStart()));
String timeEnd = (String) (DateFormat.format(&quot;HH:mm&quot;, workDayItem.getDateEnd()));
String dateStart = (String) (DateFormat.format(&quot;dd.MM.yyyy&quot;, 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, &quot;replace-remove&quot;, 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 = &quot;&quot; + workDayItem.getDateStart().getTime();
String firebaseTime = &quot;&quot; + snapshot.child(&quot;dateStart&quot;).child(&quot;time&quot;).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() &gt; 2) {
Log.i(TAG, &quot;TESTER: desc dote added&quot;);
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
else if( workDayItemList.get(position).getDesc().length() &lt; 2 
&amp;&amp; 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 doteOfDescto 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() &gt; 2;
holder.doteOfDesc.setVisibility( hasDescription ? View.VISIBLE : View.GONE);

huangapple
  • 本文由 发表于 2020年7月23日 20:56:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63054837.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定