繁体   English   中英

ListView与CheckBox再次Android

[英]ListView with CheckBox again Android

您好,我在清单视图中的chechbox有问题。 我整天都尝试,但是我做不到:/我想要:当某人单击复选框时,我想将菜单项的标题从“取消”更改为“保存”(1),在选择下一个“保存(2)”时等等。取得所选产品的编号和数量。 我得到了ID,但我认为这是错误的方式,因为当有人单击复选框时,我现在要提取一定数量的产品。 如果有人单击并下一步更改数量值怎么办?有人可以帮助我吗? Plsss

它是我的代码:

分段

    package befit.example.com.befit.Fragments;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.ami.fundapter.BindDictionary;
import com.ami.fundapter.extractors.StringExtractor;
import com.kosalgeek.android.json.JsonConverter;
import com.kosalgeek.asynctask.AsyncResponse;
import com.kosalgeek.asynctask.PostResponseAsyncTask;

import org.json.JSONArray;
import org.json.JSONException;

import java.util.ArrayList;
import java.util.HashMap;

import befit.example.com.befit.Adapter.MyFunDapter;
import befit.example.com.befit.R;
import befit.example.com.befit.Serialized.Products;

public class SearchFragment extends Fragment {

    private ListView lvSearch;
    private SearchView searchView;
    private HashMap postData;
    private PostResponseAsyncTask loginTask;
    private ArrayList<Products> productsList;
    private Bundle bundle;
    private MenuItem save;
    private RelativeLayout layoutInvisible;
    private MyFunDapter<Products> adapter;
    private ArrayList products, sizes;
    private String resultAll;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {

        bundle = this.getArguments();

        if (bundle != null) {
            String type = bundle.getString("type");
            ((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(type);
        }
        return inflater.inflate(R.layout.fragment_search, parent, false);

    }

    public void onViewCreated(View view, Bundle savedInstanceState) {

        setHasOptionsMenu(true);

        lvSearch(view);

        search(view);

        getCounterFromAdapter();

    }

    private void getCounterFromAdapter() {

        int counter = adapter.getCounter();

        if (counter != 0)
            save.setTitle("Save (" + counter + ")");
        else
            save.setTitle("Cancel");

    }
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

        inflater.inflate(R.menu.fragment_search_menu, menu);

        save = menu.findItem(R.id.save);

        super.onCreateOptionsMenu(menu, inflater);
    }

    private void lvSearch(View view) {

        lvSearch = (ListView) view.findViewById(R.id.lvSearch);

        postData = new HashMap();
        postData.put("mobile", "android");

        loginTask = new PostResponseAsyncTask(getActivity(), postData, new AsyncResponse() {

            @Override
            public void processFinish(String result) {

                resultAll = result;

                productsList = new JsonConverter<Products>().toArrayList(result, Products.class);

                BindDictionary<Products> dict = new BindDictionary<Products>();

                dict.addStringField(R.id.tvProductsName, new StringExtractor<Products>() {

                    @Override
                    public String getStringValue(Products products, int position) {
                        return products.name;
                    }
                });

                dict.addStringField(R.id.tvProductsWeight, new StringExtractor<Products>() {

                    @Override
                    public String getStringValue(Products products, int position) {
                        return products.quantity + " gram - " + products.calories + " kcal";
                    }
                });

                dict.addStringField(R.id.tvSearchSize, new StringExtractor<Products>() {

                    @Override
                    public String getStringValue(Products products, int position) {
                        return products.quantity + "";
                    }
                });

                dict.addStringField(R.id.tvSearchCalories, new StringExtractor<Products>() {

                    @Override
                    public String getStringValue(Products products, int position) {
                        return "Calories: " + products.calories + " kcal";
                    }
                });

                dict.addStringField(R.id.tvSearchFat, new StringExtractor<Products>() {

                    @Override
                    public String getStringValue(Products products, int position) {
                        return "Fat: " + products.fat + " gram";
                    }
                });

                dict.addStringField(R.id.tvSearchCarbs, new StringExtractor<Products>() {

                    @Override
                    public String getStringValue(Products products, int position) {
                        return "Carbs: " + products.carbs + " gram";
                    }
                });

                dict.addStringField(R.id.tvSearchProtein, new StringExtractor<Products>() {

                    @Override
                    public String getStringValue(Products products, int position) {
                        return "Protein: " + products.protein + " gram";
                    }
                });

                adapter = new MyFunDapter<Products>(getActivity(), productsList, R.layout.list_view_search, dict);

                lvSearch.setAdapter(adapter);
            }
        });

        loginTask.execute("http://10.0.3.2/befit/products.php");

        lvSearch.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, final View adapterView, int position, long id) {

                layoutInvisible = (RelativeLayout) adapterView.findViewById(R.id.layoutInvisible);

                if (layoutInvisible.getVisibility() == View.VISIBLE)
                    layoutInvisible.setVisibility(View.GONE);
                else
                    layoutInvisible.setVisibility(View.VISIBLE);

                getCounterFromAdapter();
            }
        });
    }

    private void search(View view) {

        searchView = (SearchView) view.findViewById(R.id.searchView);
        searchView.setQueryHint("Search...");
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {

                //adapter.getFilter().filter(newText);

                return false;
            }
        });

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.save) {

            int sizeOfProducts = adapter.getClickedProducts().size();

            if (sizeOfProducts > 0) {
                products = adapter.getClickedProducts();
                sizes = adapter.getClickedSize();

                postData = new HashMap();
                postData.put("mobile", "android");

                try {
                    JSONArray jArray = new JSONArray(resultAll);

                    postData.put("p1", jArray.getJSONObject(Integer.parseInt(products.get(0).toString())).getInt("id_produktu"));
                    postData.put("r1", Integer.parseInt(sizes.get(0).toString()));

                    if (sizeOfProducts > 1) {
                        postData.put("p2", jArray.getJSONObject(Integer.parseInt(products.get(1).toString())).getInt("id_produktu"));
                        postData.put("r2", Integer.parseInt(sizes.get(1).toString()));
                    }

                    if (sizeOfProducts > 2) {
                        postData.put("p3", jArray.getJSONObject(Integer.parseInt(products.get(2).toString())).getInt("id_produktu"));
                        postData.put("r3", Integer.parseInt(sizes.get(2).toString()));
                    }

                    if (sizeOfProducts > 3) {
                        postData.put("p4", jArray.getJSONObject(Integer.parseInt(products.get(3).toString())).getInt("id_produktu"));
                        postData.put("r4", Integer.parseInt(sizes.get(3).toString()));
                    }


                } catch (JSONException e) {
                    e.printStackTrace();
                }
/*
                loginTask = new PostResponseAsyncTask(getActivity(), postData, new AsyncResponse() {


                    @Override
                    public void processFinish(String s) {

                    }
                });

                loginTask.execute("10.0.3.2/products.php");
*/

                return true;
            }
        }
        return super.onOptionsItemSelected(item);
    }
}

适配器

package befit.example.com.befit.Adapter;


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.ami.fundapter.BindDictionary;
import com.ami.fundapter.FunDapterUtils;
import com.ami.fundapter.interfaces.FunDapterFilter;

import java.util.ArrayList;
import java.util.List;

import befit.example.com.befit.R;
import interfaces.LongExtractor;

/**
 * A generic adapter that takes a BindDictionary and data and shows them. Does
 * basic validation for you for all fields and also handles the ViewHolder
 * pattern.
 *
 * @param <T>
 * @author Ami G
 */
public class MyFunDapter<T> extends BaseAdapter implements Filterable {

    protected List<T> mDataItems;
    protected List<T> mOrigDataItems;
    protected LongExtractor<T> idExtractor;
    protected final Context mContext;
    private final int mLayoutResource;
    private final BindDictionary<T> mBindDictionary;
    private int oddColorRes;
    private int evenColorRes;
    private FunDapterFilter<T> funDapterFilter;
    private Filter mFilter;
    public int counter = 0;
    private ArrayList<String> products, size;

    /**
     * A generic adapter that takes a BindDictionary and data and shows them.
     * Does basic validation for you for all fields and also handles the
     * ViewHolder pattern.
     *
     * @param context
     * @param dataItems      - An arraylist of model items
     * @param layoutResource - resource ID of a layout to inflate for each item. (Example:
     *                       R.layout.list_item)
     * @param dictionary     - The dictionary that will match between fields and data.
     */
    public MyFunDapter(Context context, List<T> dataItems, int layoutResource,
                       BindDictionary<T> dictionary) {
        this(context, dataItems, layoutResource, null, dictionary);
    }

    /**
     * A generic adapter that takes a BindDictionary and data and shows them.
     * Does basic validation for you for all fields and also handles the
     * ViewHolder pattern.
     *
     * @param context
     * @param dataItems      - An arraylist of model items
     * @param layoutResource - resource ID of a layout to inflate for each item. (Example:
     *                       R.layout.list_item)
     * @param idExtractor    - The extractor that will get stable ids from the data item
     * @param dictionary     - The dictionary that will match between fields and data.
     */


    public MyFunDapter(Context context, List<T> dataItems, int layoutResource,
                       LongExtractor<T> idExtractor, BindDictionary<T> dictionary) {
        this.mContext = context;
        this.mDataItems = dataItems;
        this.mOrigDataItems = dataItems;
        this.mLayoutResource = layoutResource;
        this.idExtractor = idExtractor;
        this.mBindDictionary = dictionary;
    }

    /**
     * Replace the current dataset with a new one and refresh the views. This
     * will call notifyDataSetChanged() for you.
     *
     * @param dataItems
     */
    public void updateData(List<T> dataItems) {
        this.mDataItems = dataItems;
        this.mOrigDataItems = dataItems;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (mDataItems == null || mBindDictionary == null) return 0;

        return mDataItems.size();
    }

    @Override
    public T getItem(int position) {
        return mDataItems.get(position);
    }

    @Override
    public boolean hasStableIds() {
        if (idExtractor == null) return super.hasStableIds();
        else return true;
    }

    @Override
    public long getItemId(int position) {
        if (idExtractor == null) return position;
        else return idExtractor.getLongValue(getItem(position), position);
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        // Inflate a new view or use a recycled view.
        View v = convertView;
        final MyGenericViewHolder holder;
        if (null == v) {
            LayoutInflater vi =
                    (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(mLayoutResource, null);
            holder = new MyGenericViewHolder();
            holder.root = v;

            holder.tvSearchFat = (TextView) v.findViewById(R.id.tvSearchFat);
            holder.tvSearchSize = (TextView) v.findViewById(R.id.tvSearchSize);
            holder.layoutInvisible = (RelativeLayout) v.findViewById(R.id.layoutInvisible);
            holder.checkBox = (CheckBox) v.findViewById(R.id.checkBox);

            // init the sub views and put them in a holder instance
            FunDapterUtils.initViews(v, holder, mBindDictionary);

            v.setTag(holder);
        } else {
            holder = (MyGenericViewHolder) v.getTag();
        }

        // Show the data
        final T item = getItem(position);
        showData(item, holder, position);

        holder.layoutInvisible.setVisibility(View.GONE);

        products = new ArrayList<String>();

        size = new ArrayList<String>();

        holder.checkBox.setTag(R.id.ID_TAG, position);
        holder.checkBox.setTag(R.id.SIZE_TAG, holder.tvSearchSize.getText().toString());
        holder.checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String id = String.valueOf(v.getTag(R.id.ID_TAG));
                String sizeOfProduct = String.valueOf(v.getTag(R.id.SIZE_TAG));

                if(holder.checkBox.isChecked()) {
                    counter++;
                    products.add(id);
                    size.add(sizeOfProduct);
                }
                else{
                    counter--;
                    products.remove(id);
                    size.remove(sizeOfProduct);
                }
            }
        });

        return v;
    }

    public ArrayList getClickedProducts(){

        return products;
    }

    public ArrayList getClickedSize(){

        return size;
    }

    public int getCounter(){

        return counter;
    }

    private void showData(T item, MyGenericViewHolder holder, int position) {

        // handles alternating background colors if selected
        if (oddColorRes > 0 && evenColorRes > 0) {
            if (position % 2 == 0) {
                holder.root.setBackgroundColor(mContext.getResources().getColor(evenColorRes));
            } else {
                holder.root.setBackgroundColor(mContext.getResources().getColor(oddColorRes));
            }
        }

        FunDapterUtils.showData(item, holder, position, mBindDictionary);
    }

    public MyFunDapter<T> setAlternatingBackground(int oddColorRes, int evenColorRes) {

        if (oddColorRes <= 0 || evenColorRes <= 0) {
            throw new IllegalArgumentException("Color parameters are illegal");
        }

        this.oddColorRes = oddColorRes;
        this.evenColorRes = evenColorRes;

        return this;
    }

    /**
     * @param idExtractor - used to extract a stable id from the underlying data item (like a database id or something)
     */
    public void setIdExtractor(LongExtractor<T> idExtractor) {
        this.idExtractor = idExtractor;
    }

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

    /**
     * Use this method to enable filtering in the adapter.
     *
     * @param filter - a filter implementation for your adapter.
     */
    public void initFilter(FunDapterFilter<T> filter) {

        if (filter == null)
            throw new IllegalArgumentException("Cannot pass a null filter to FunDapter");

        this.funDapterFilter = filter;

        mFilter = new Filter() {

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

                @SuppressWarnings("unchecked") List<T> list = (List<T>) results.values;

                if (results.count == 0) {
                    resetData();
                } else {
                    mDataItems = list;
                }

                notifyDataSetChanged();
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                FilterResults results = new FilterResults();
                if (constraint == null || constraint.length() == 0) {

                    // No constraint - no point in filtering.
                    results.values = mOrigDataItems;
                    results.count = mOrigDataItems.size();
                } else {
                    // Perform the filtering operation

                    List<T> filter =
                            funDapterFilter.filter(constraint.toString(), mOrigDataItems);

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

                }

                return results;
            }
        };
    }



    public void resetData() {
        mDataItems = mOrigDataItems;
    }
}

请帮我:))

利用接口获取适配器中已检查项目的数量,然后将inavlidateMenu()与一个值

接口

public interface MyAdapterClickInterface{
    public void itemChecked(int position);
}

现在在您的片段中将其更改为

public class SearchFragment extends Fragment implements MyAdapterClickInterface{
int itemsChecked = 0; //this will keep a note of items to be shown in menu
// if you want to save items also then add an attribute to your Products class to get checked item

实施方法

public void itemChecked(int position){
    itemsChecked++;
    invalidateOptionsMenu();
}

在片段中初始化适配器时,将该调用更改为:

adapter = new MyFunDapter<Products>(getActivity(), productsList, R.layout.list_view_search, dict, this);//this means fragments implementations

现在在您的适配器构造函数中

MyAdapterClickInterface checkedListener;
public MyFunDapter(Context context, List<T> dataItems, int layoutResource,
                       LongExtractor<T> idExtractor, BindDictionary<T> dictionary, MyAdapterClickInterface checkedListener) {
        this.mContext = context;
        this.checkedListener = checkedListener; //making use of interface instance
...
}

现在终于在检查您的物品时

holder.checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            if(holder.checkBox.isChecked()){
            checkedListener.itemChecked(position);
            //or some other method to save your checks..
            }

这将做您想做的.. :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM