当前位置: 首页 > 知识库问答 >
问题:

将arraylist返回到原始列表

杜哲彦
2023-03-14

注:[2017年1月11日]RestInfoAdapter.java的源代码已经更改和更新(参见下面的第2项)

我一直在尝试通过保留原始输入列表的备份/副本来使我的搜索视图返回到原始列表。但是,它根本不起作用。我的这个问题包括使用自定义类的RecyclerView和ArrayList。

rInf_LIST是一个名为<code>RestInfo
我是如何尝试的

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_vacancy_list);

    srchVw = (SearchView) findViewById(R.id.search);
    srchVw.setOnQueryTextListener(new SearchView.OnQueryTextListener()
    {
        @Override
        public boolean onQueryTextSubmit(String query)
        {
            adapter.getFilter().filter(query);
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText)
        {
            adapter.getFilter().filter(newText);
            return true;
        }
    });

    /*miscellaneous codes*/

    rInf_LIST = new ArrayList<>();
    new NetworkTask(this, "listfirstTime").execute();

    //Setup Recycler View with the appropriate adapter and layout.
    recyclVw = (RecyclerView) findViewById(R.id.recyclerView);
    adapter = new RestInfoAdapter(this, rInf_LIST);
    GridLayoutManager glm = new GridLayoutManager(this, 1);

    recyclVw.setLayoutManager(glm);
    recyclVw.setAdapter(adapter);

    refresh = (SwipeRefreshLayout) findViewById(R.id.refresh);
    refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
    {
        @Override
        public void onRefresh()
        {
            new Handler().post(new Runnable()
            {
                @Override
                public void run()
                {
                    new NetworkTask(VacancyList.this, "list").execute();
                    Toast.makeText(VacancyList.this, "Refreshed", Toast.LENGTH_SHORT).show();
                    refresh.setRefreshing(false);
                }
            });
        }
    });

RestInfoAdapter.java适配器类,以便RestInfo可以呈现在卡片视图中(因此,多个,recyclerview)

public class RestInfoAdapter extends RecyclerView.Adapter<RestInfoAdapter.RestInfo_ViewHolder> implements Filterable
{
public Filter filter;

private Context context;
private ArrayList<RestInfo> rInf_LIST;
private ArrayList<RestInfo> filteredList;
//Java Array starts at 0
int selectedItemID = -1;

public Context getContext()
{return context;}

public RestInfoAdapter(Context mContext, ArrayList<RestInfo> rInf)
{
    this.context = mContext;
    rInf_LIST = rInf;
    filteredList = rInf;
    filter = new rInf_LIST_Filter();
}

@Override
public RestInfo_ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
    View itemVw = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
    return new RestInfo_ViewHolder(itemVw);
}

//Binds 1 RestInfo to the UI elements
@Override
public void onBindViewHolder(final RestInfo_ViewHolder holder, int position)
{
    RestInfo rInf = filteredList.get(position);
    holder.rName.setText(rInf.getRestName());
    holder.rLot.setText(rInf.getRestLot());
    holder.rVacancy_PROGBAR.setProgress(rInf.getResVacant());
    holder.progBarVal.setText(Integer.toString(rInf.getResVacant()/10));
}

@Override
public int getItemCount()
{
    return rInf_LIST.size();
}

@Override
public Filter getFilter()
{
    return filter;
}

private class rInf_LIST_Filter extends Filter
{
    @Override
    protected FilterResults performFiltering(CharSequence charSequence)
    {
        FilterResults results = new FilterResults();
        ArrayList<RestInfo> temp = new ArrayList<>();

        if(charSequence.length() == 0)
            temp.addAll(rInf_LIST);
        else
        {
            String filtrate = charSequence.toString().toLowerCase().trim();

            for(int count = 0; count < rInf_LIST.size(); count++)
            {
                if(rInf_LIST.get(count).getRestName().toLowerCase().contains(filtrate))
                    temp.add(rInf_LIST.get(count));
            }
        }

        results.values = temp;
        results.count = temp.size();

        return results;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults)
    {
        Log.d("charSequence : ", Integer.toString(charSequence.length()));
        if(true)
        {
            filteredList.clear();
            filteredList.addAll((ArrayList<RestInfo>) filterResults.values);
            notifyDataSetChanged();
        }
    }
}

public class RestInfo_ViewHolder extends RecyclerView.ViewHolder
{
    public TextView rName, rLot, progBarVal;
    public ProgressBar rVacancy_PROGBAR;

    public RestInfo_ViewHolder(final View itemView)
    {
        super(itemView);

        rName = (TextView)itemView.findViewById(R.id.txtVw_RestName);
        rLot = (TextView)itemView.findViewById(R.id.txtVw_RestLot);
        progBarVal = (TextView)itemView.findViewById(R.id.progBarTextValue);

        rVacancy_PROGBAR = (ProgressBar)itemView.findViewById(R.id.progBar);

        itemView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view) {
                selectedItemID = getAdapterPosition();
                Intent intent = new Intent(context, RestaurantInfo.class);

                intent.putExtra("selected_Rest", filteredList.get(selectedItemID));
                context.startActivity(intent);
            }
        });
    }
}

}

< code>RestInfo的数据结构和获取restName的相关方法。

//Displayed in CardView (and RestaurantInfo)
//protected ImageView imgVw;
protected String restName;
protected String restLot;
protected String restLoc;
protected int restVacant;

//Displayed in RestaurantInfo
protected String restType;
protected String restNo;
protected String restEmail;

//Displayed for Admin
protected String restOwn;
protected int restID;

//Status
private boolean objIS_EMPTY = true;

public String getRestName(){
    return restName;
}

Logcat using Log.D 这是在 publishResults 方法中完成的。此日志记录的目的是检查列表是否为空。

[PRE]标记在< code>if(filterResults.count)之前

01-09 14:33:06.357 23159-23159/fyp。inrestaurant D/[PRE]

01-09 14:33:06.357 23159-23159/fyp。inrestaurant D/[PRE]

01-09 14:33:06.357 23159-23159/fyp。inrestaurant D/[PRE]

[邮政]邮政总局

[邮政]邮政总局

[邮政]邮政总局

这适用于编辑1中的条件为真的情况

01-09 14:39:31.027 23159-23159/fyp.inrestaurantD/[PRE]

01-09 14:39:31.027 23159-23159/fyp.inrestaurantD/[PRE]

01-09 14:39:31.027 23159-23159/fyp.inrestaurantD/[PRE]

2007年12月15日,美国纽约市,2007年12月27日

2007年12月15日,美国纽约市,2007年12月27日

2007年12月15日,美国纽约市,2007年12月27日

添加了用于记录发布结果的更新代码

protected void publishResults(CharSequence charSequence, FilterResults filterResults)
    {
        Log.d("[PRE] filterResults", Integer.toString(filterResults.count)+"\n");
        Log.d("[PRE] rInf_LIST", Integer.toString(rInf_LIST.size())+"\n");
        Log.d("[PRE] rInf_LIST_cpy", Integer.toString(rInf_LIST_cpy.size())+"\n");
        if(filterResults.count > 0)
        {
            rInf_LIST.clear();
            rInf_LIST.addAll((ArrayList<RestInfo>) filterResults.values);
            Log.d("[POST] filterResults", Integer.toString(filterResults.count)+"\n");
            Log.d("[POST] rInf_LIST", Integer.toString(rInf_LIST.size())+"\n");
            Log.d("[POST] rInf_LIST_cpy", Integer.toString(rInf_LIST_cpy.size())+"\n");
            notifyDataSetChanged();
        }
        else
        {
            rInf_LIST.clear();
            rInf_LIST.addAll(rInf_LIST_cpy);
            Log.d("[POST] filterResults", Integer.toString(filterResults.count)+"\n");
            Log.d("[POST] rInf_LIST", Integer.toString(rInf_LIST.size())+"\n");
            Log.d("[POST] rInf_LIST_cpy", Integer.toString(rInf_LIST_cpy.size())+"\n");
            notifyDataSetChanged();
        }
    }

添加了新的代码建议

public RestInfoAdapter(Context mContext, ArrayList<RestInfo> rInf)
{
    this.context = mContext;
    rInf_LIST = rInf;
    rInf_LIST_cpy = new ArrayList<>(rInf);
    filteredList = new ArrayList<>();
    filter = new rInf_LIST_Filter();
}

日志不显示改进(这是false)

01-09 14:51:26.687 8198-8198/fyp.inrestaurant D/[PRE]

01-09 14:51:26.687 8198-8198/fyp.inrestaurant D/[PRE]

01-09 14:51:26.687 8198-8198/fyp.inrestaurant D/[PRE]

01-09 14:51:26.687 8198-8198/fyp.inrestaurantD/[POST]

01-09 14:51:26.687 8198-8198/fyp.inrestaurantD/[POST]

01-09 14:51:26.687 8198-8198/fyp.inrestaurantD/[POST]


当假设条件为真时。(5)数据集中有3个包含字符s)

[PRE]参考译文

[PRE]参考译文

[PRE]参考译文

01-09 14:53:01.427 8198-8198/fyp.inrestaurantD/[POST]

01-09 14:53:01.427 8198-8198/fyp.inrestaurantD/[POST]

01-09 14:53:01.427 8198-8198/fyp.inrestaurantD/[POST]

由于存在有关rInf_List从何处获得其价值的问题,因此以下是onPostExecute()的代码和相关方法。

P/S@beeb,我犯了一个错误,该方法不是在onpostexecute中,而是在processfinish中,因为NetworkTask是它自己的另一个类(因为有多个活动需要执行NetworkTasks,所以我创建了一个类来减少代码库)

TL:dr;代码版本:processFinish将输出设置为JSON数组。然后,这个数组将通过一个定制的转换方法JSONArray_RestInf()将其成员分配给temp (RestInfo类型)。这个临时变量将通过RestInfo_ArrLst()方法添加到全局变量rInf_List中。如果添加了新的项目,它将调用notifyItemAdded(int position)。如果前一项是相同的,但是给出了附加数据,那么将在相应的位置调用notifyItemChanged。

@Override
public void processFinish(String output)
{
    boolean firstTime = Boolean.parseBoolean(output.substring(0, output.indexOf('e') + 1));
    output = output.substring(output.indexOf('e') + 1);

    if (!output.isEmpty())
    {
        try
        {
            jsArr = new JSONArray(output);

            for (int ctr = 0; ctr < jsArr.length(); ctr++)
            {
                RestInfo temp = JSONArray_RestInf(ctr);
                RestInfo_ArrLst(temp, firstTime);
            }
            Log.w("Size...", Integer.toString(rInf_LIST.size()));
        }
        catch (JSONException e)
        {
            e.printStackTrace();

        }
    }
    else
        Toast.makeText(VacancyList.this, "Failed to retrieve list", Toast.LENGTH_SHORT).show();
}

//Converts the JSONArray to RestInfo
private RestInfo JSONArray_RestInf(final int index)
{
    RestInfo tempInf;

    try
    {
        ArrayList<String> tempArrLst = new ArrayList<>();

        //Converts JSONArray to ArrayList of strings
        for (String ctr : ELEMENTS)
        {
            tempArrLst.add(jsArr.getJSONObject(index).get(ctr).toString());
        }

        tempInf = new RestInfo(Integer.parseInt(tempArrLst.get(0)), tempArrLst.get(1), tempArrLst.get(2), tempArrLst.get(3), tempArrLst.get(4), Integer.parseInt(tempArrLst.get(5)), tempArrLst.get(6), tempArrLst.get(7), tempArrLst.get(8));

        return tempInf;
    }
    catch (JSONException e)
    {
        e.printStackTrace();

        return new RestInfo(0, "", "", "", "", 0, "", "", "");
    }
}

//Adds the temporary restaurant info to the array.
private void RestInfo_ArrLst(RestInfo tempInf, boolean firstT)
{
    if (!tempInf.getEMPTY_Status())
    {
        if (firstT)
        {
            rInf_LIST.add(tempInf);
            adapter.notifyDataSetChanged();
        }
        else
        {
            boolean hasSameField;
            ArrayList<Boolean> hasChanged = new ArrayList<>(), isSimilar = new ArrayList<>();
            ArrayList<Integer> changedPos = new ArrayList<>();

            //Loop to check for duplicates
            for (int ctr = 0; ctr < rInf_LIST.size(); ctr++)
            {
                hasSameField = (tempInf.checkFields(rInf_LIST.get(ctr)));
                if (tempInf.getRestID() == rInf_LIST.get(ctr).getRestID() && !hasSameField)
                {
                    rInf_LIST.set(ctr, tempInf);
                    changedPos.add(ctr);
                    hasChanged.add(true);
                }
                else if (tempInf.getRestID() == rInf_LIST.get(ctr).getRestID() && hasSameField)
                {
                    isSimilar.add(true);
                }
            }

            for(int ctr = 0; ctr < hasChanged.size(); ctr++)
            {
                if (!hasChanged.get(ctr)&& !isSimilar.get(ctr))
                {
                    rInf_LIST.add(tempInf);
                    adapter.notifyItemInserted(adapter.getItemCount() - 1);
                }
                else if (hasChanged.get(ctr))
                {
                    adapter.notifyItemChanged(changedPos.get(ctr));
                }
            }
        }
    }
}

共有3个答案

林鸿飞
2023-03-14

首先,您将使用空列表初始化适配器:

rInf_LIST = new ArrayList<>(); // you create an empty list
new NetworkTask(this, "listfirstTime").execute();

//Setup Recycler View with the appropriate adapter and layout.
recyclVw = (RecyclerView) findViewById(R.id.recyclerView);
adapter = new RestInfoAdapter(this, rInf_LIST); // at this point your list is already empty

我们看不到您添加项目的位置(我认为它在NetworkTask中的onPostExecute()中,对吗?)。

第二:您必须创建原始列表的副本,因为您不想在过滤时修改原始列表:rInf_LIST_cpy = new ArrayList

第三:在您的过滤器中,您只需要执行以下操作:

@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
  rInf_LIST.clear();
  rInf_LIST.addAll((ArrayList<RestInfo>) filterResults.values);
  notifyDataSetChanged();
}

因为您已经将正确的对象添加到performFilting()中的结果中

有关更多信息,请查看此链接的已接受答案:在RecyclerView with Cards上添加搜索过滤器?

白志勇
2023-03-14

您正在使用这种代码创建一个新列表:filteredList.add(rInf_list_cpy.get(count));

尝试创建一个新对象RestInfo并将值保存到此对象,然后添加到列表

皇甫聪
2023-03-14

这将解决你的问题:

public RestInfoAdapter(Context mContext, ArrayList<RestInfo> rInf)
{
    this.context = mContext;
    rInf_LIST = rInf;
    rInf_LIST_cpy = new ArrayList<>(rInf);  // Create a new object. You don't want to use the same reference. :)
    filteredList = new ArrayList<>();
    filter = new rInf_LIST_Filter();
}
 类似资料:
  • 我不确定如何返回arraylist(删除null子列表),以及删除非null子列表中的null项。如果list为Null,则返回空arraylist。这就是我到目前为止所做的。

  • 我试图重构我的代码,在这样做的时候,我试图把SQL查询留给一个类。我试图将参数从html表单传递到servlet,然后servlet将这些参数传递到其方法params中的ApplicationDao,后者(应该)以用户对象arraylist的形式返回结果集。当我传递电子邮件时,它会说找不到列,尽管当我在servlet中执行完全相同的操作时,我正在重构结果。显然,由于这个问题,数组列表正在将长度0传

  • 问题内容: 该方法返回的表示形式。这里返回的对象是数组支持的,但不是对象。 我正在寻找对象返回值与对象之间的差异- 一种快速的来源,可以告诉它们而无需深入研究代码。 TIA。 问题答案: 当您调用Arrays.asList时,它不会返回。它返回一个由原始源数组支持的固定大小列表。换句话说,它是使用Java的基于集合的API公开的数组的视图。 您不能向其中添加元素,也不能从中删除元素。如果您尝试从中

  • 问题内容: 我想将ArrayList保存到SharedPreferences,因此需要将其转换为字符串然后返回,这就是我正在做的事情: 我可以用它来检索它,但我不知道如何将arrayString转换回ArrayList。如何做呢? 我的数组看起来像: 问题答案: 您有2个选择: 手动解析字符串并重新创建arraylist。这将是非常乏味的。 使用Google的Gson库之类的JSON库,以JSON

  • 环境 期望的行为 我想更新文档并返回原始文档。 实际行为 正在返回更新的文档,而不是原始文档。 我试过的 起初,我在查看findAndModify: http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#findAndModify 然而,那里的文档表示它已被弃用,并使用findOneAndUpdate、findOn

  • 这让我快疯了。我有一个简单的eclipse项目,其中有一个src文件夹和一个类。但我似乎无法让getResource找到它。我做错了什么? 如果我右键单击类名,路径是testsprroject/src/ContextTest。java,根据运行配置中的classpath选项卡,默认的类路径是TestProject。 它不适用于