【问题标题】:Parsing a JSON and extracting items with condition解析 JSON 并根据条件提取项目
【发布时间】:2019-07-24 15:49:15
【问题描述】:

我的问题类似于Implementing Search Filter in Adapter Class which parses a json array (without using pojo) 但我想尝试以不同的方式解决这个问题。我有一个必须根据条件过滤的元素列表,一旦验证了此条件,我想从 json 数组中检索验证它的元素。在此示例中,我根据元素的名称过滤了元素,并且在 setContentValue () 中,我将设置代码和十六进制字符串,仅采用具有该名称的那些元素,否则在过滤期间名称与代码具有不同的索引,并且十六进制字符串。我怎么能那样做?

片段

public class ColorViewFragment extends Fragment {

private RecyclerView recyclerView;
private JSONArray json;
private ColorListAdapter adapter;

private EditText editColor;

@Nullable @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.color_list, container, false);
    this.recyclerView = view.findViewById(R.id.recyclerView);

    /*
    try {
        this.recyclerView.setAdapter(new ColorListAdapter(this.json));
    } catch (JSONException e) {
        e.printStackTrace();
    }
    */

    try {
        adapter = new ColorListAdapter(json);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    recyclerView.setAdapter(adapter);


    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
    this.recyclerView.setLayoutManager(layoutManager);

    //
    editColor = view.findViewById(R.id.editText);
    editColor.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            ColorViewFragment.this.adapter.getFilter().filter(s);

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

    return view;
}

public void setJSON(JSONArray newJson){
    this.json = newJson;
}

适配器

public class ColorListAdapter extends RecyclerView.Adapter implements Filterable {

private JSONArray colorList;

private List<String> colorListFiltered = new ArrayList<String>();

public ColorListAdapter(JSONArray json) throws JSONException {
    super();
    if (json != null) {
        this.colorList = json;

            for (int i=0;i<json.length();i++){
                //colorListFiltered.add((colorList.getString(i)));
                colorListFiltered.add(json.getJSONObject(i).getString("Name"));
            }
    }
}


@Override
public Filter getFilter() {
    return new colorFilter();
}


@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_color_view, viewGroup, false);
    return new ColorListHolder(view);
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
    try {
        ((ColorListHolder) viewHolder).setContentValue(i);
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

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

private class ColorListHolder extends RecyclerView.ViewHolder {

    private TextView colorCodeText;
    private TextView colorNameText;
    private CardView imageView;

    public ColorListHolder(@NonNull View itemView) {
        super(itemView);
        this.colorCodeText = itemView.findViewById(R.id.colorCode_text);
        this.colorNameText = itemView.findViewById(R.id.colorName_text);
        this.imageView = itemView.findViewById(R.id.colorView);
    }

    public void setContentValue(int index) throws JSONException {

        this.colorNameText.setText(colorListFiltered.get(index));
        //this.colorNameText.setText(((JSONObject) colorList.get(index)).getString("Name"));
        this.colorCodeText.setText(((JSONObject) colorList.get(index)).getString("ColorCode"));
        this.imageView.setCardBackgroundColor(Color.parseColor(((JSONObject) colorList.get(index)).getString("HexString")));

    }
}


public class colorFilter extends Filter{

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        FilterResults Result = new FilterResults();
        // if constraint is empty return the original names

        if(constraint.length() == 0 ) {
            ArrayList<String> arrColorList = new ArrayList<>();
            for (int i = 0; i < colorList.length(); i++) {
                try {
                    arrColorList.add(colorList.getJSONObject(i).getString("Name"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            Result.values = arrColorList;
            Result.count = arrColorList.size();
            return Result;
        }

        /*if(constraint.length() == 0 ){
            Result.values = colorList;
            Result.count = colorList.length();
            return Result;*/

        else {

            List<String> Filtered_Names = new ArrayList<String>();
            String filterString = constraint.toString().toLowerCase();
            String filterableString = "";

            for (int i = 0; i < colorList.length(); i++) {
                try {
                    filterableString = (colorList.getJSONObject(i)).getString("Name");
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                if (filterableString.toLowerCase().contains(filterString)) {
                    Filtered_Names.add(filterableString);
                }
            }

            Result.values = Filtered_Names;
            Result.count = Filtered_Names.size();
            return Result;

        }

    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {

        colorListFiltered = (ArrayList<String>) results.values;
        notifyDataSetChanged();
    }
}

【问题讨论】:

  • 这里有什么问题?过滤不工作?或者它可以但工作错误?
  • 感谢您的回答。所以......列表按名称过滤,但是,当我输入名称时,似乎名称被过滤,但每个名称在视图中都有错误的代码和错误的十六进制字符串(使用 parsecolor 着色卡片)。我认为因为在 setContentValue() 中我需要提取名称等于我过滤的值的值。但我不知道如何..我也尝试过stackoverflow.com/questions/57134956/… 但不起作用..

标签: java android arrays json


【解决方案1】:

我接近解决方案,列出加载并被过滤,但是当我删除单词时,我得到一个 ClassCastException: String cannot be cast to JSONObject (in setContentValue)。

public class ColorListAdapter extends RecyclerView.Adapter implements Filterable {

        private List<JSONObject> colorList = new ArrayList<JSONObject>();

        private List<JSONObject> colorListFiltered = new ArrayList<JSONObject>();

        public ColorListAdapter(JSONArray json) throws JSONException {

            super();
            if (json != null) {


                for(int i=0; i<json.length(); i++) {

                    JSONObject jsonObj = json.getJSONObject(i);
                    colorList.add(jsonObj);

                    colorListFiltered = colorList;

                }

            }
        }


        @Override
        public Filter getFilter() {
            return new colorFilter();
        }


        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_color_view, viewGroup, false);
            return new ColorListHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
            try {
                ((ColorListHolder) viewHolder).setContentValue(i);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public int getItemCount() {

            return this.colorListFiltered.size();

        }

        private class ColorListHolder extends RecyclerView.ViewHolder {

            private TextView colorNameText;
            private TextView colorCodeText;
            private CardView imageView;

            public ColorListHolder(@NonNull View itemView) {
                super(itemView);
                this.colorCodeText = itemView.findViewById(R.id.colorCode_text);
                this.colorNameText = itemView.findViewById(R.id.colorName_text);
                this.imageView = itemView.findViewById(R.id.colorView);
            }


            public void setContentValue(final int index) throws JSONException {


                this.colorNameText.setText(colorListFiltered.get(index).getString("Name"));
                this.colorCodeText.setText(colorListFiltered.get(index).getString("ColorCode"));
                this.imageView.setCardBackgroundColor(Color.parseColor(colorListFiltered.get(index).getString("HexString")));

                }
        }


        //filtro su Name
        public class colorFilter extends Filter{

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                FilterResults Result = new FilterResults();

                // if constraint is empty return the original names
                if(constraint.length() == 0 ) {
                    ArrayList<String> arrNameList = new ArrayList<>();
                    for (int i = 0; i < colorList.size(); i++) {
                        try {
                            arrNameList.add(colorList.get(i).getString("Name"));
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                    Result.values = arrNameList;
                    Result.count = arrNameList.size();
                    return Result;
                }

                else {

                    List<JSONObject> Filtered_Names = new ArrayList<JSONObject>();
                    String filterString = constraint.toString().toLowerCase();
                    String filterableString = "";

                    for (int i = 0; i < colorList.size(); i++) {
                        try {
                            filterableString = (colorList.get(i)).getString("Name");
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                        if (filterableString.toLowerCase().contains(filterString)) {
                            Filtered_Names.add(colorList.get(i));
                        }
                    }

                    Result.values = Filtered_Names;
                    Result.count = Filtered_Names.size();
                    return Result;

                }

            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

                colorListFiltered = (ArrayList<JSONObject>) results.values;
                notifyDataSetChanged();
            }
        }

    }

【讨论】:

    【解决方案2】:

    您使用colorListFiltered 表示名称,但您使用colorList 表示setContentValue 中的十六进制代码。前两个列表是相同的,但是当您过滤 colorListFiltered 时,它们会变得不同。

    改变这个,

     private JSONArray colorList;
    
     private List<String> colorListFiltered = new ArrayList<String>();
    

    到

    private List<JSONObject> colorList = new ArrayList<JSONObject>();
    
    private List<JSONObject> colorListFiltered = new ArrayList<JSONObject>();
    

    还有你的performFiltering

    List<JSONObject> Filtered_Names = new ArrayList<JSONObject>();
                    String filterString = constraint.toString().toLowerCase();
                    String filterableString = "";
    
                    for (int i = 0; i < colorList.size(); i++) {
                        try {
                            filterableString = (colorList.get(i)).getString("Name");
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
    
                        if (filterableString.toLowerCase().contains(filterString)) {
                            Filtered_Names.add(colorList.get(i));
                        }
                    }
    

    setContentValue:

    public void setContentValue(int index) 抛出 JSONException {

    this.colorNameText.setText(colorListFiltered.get(index).getString("Name"));
    this.colorCodeText.setText(colorListFiltered.get(index).getString("ColorCode"));
    this.imageView.setCardBackgroundColor(Color.parseColor(colorListFiltered.get(index).getString("HexString"));
    

    }

    【讨论】:

    • 感谢您的帮助。所以...我认为 colorList.getJSONObject(i) 应该是 colorList.get(i) 和 colorListFiltered = (ArrayList) results.values in publishResults;现在我需要在构造函数中更改 colorList 和 colorListfiltered 初始化..如何?
    • 我没有尝试就回答了,所以它可能有一些你需要修复的错误。让我们试试:)
    • 我接近解决方案,列出加载并被过滤,但是当我删除单词时,我得到一个 ClassCastException: String cannot be cast to JSONObject (in setContentValue)。也许是因为当我删除单词时,它被 setText 视为一个对象......如何解决这个问题?谢谢。
    • this.colorNameText.setText 或 this.colorCodeText.setText 哪一行?
    • this.colorNameText.setText and "Unchecked cast: 'java.lang.Object' to 'java.util.List" in colorListFiltered = (List) 结果.values;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    相关资源
    最近更新 更多