FragmentList - 尝试更改项目背景颜色

FragmentList - Trying to change item background color

我试图在单击此项后更改 FragmentList 项的背景颜色并确认显示的 AlertDialog,它有效但它正在更改 clicled 项旁边的其他项.... 这是我下面的所有代码...

public class RefrigeranteFragment extends ListFragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

public View SelectedView;

String[] refrigerantes = new String[] {
        "Coca Cola",
        "Coca Cola Zero",
        "Fanta Uva",
        "Guaraná Antartica",
        "Guaraná Antartica Zero",
        "Sukita",
        "Sukita Laranja",
        "Sprite",
        "Guaraná Antartica",
        "Sukita Uva"
};

// Array of strings to store currencies
String[] precos = new String[]{
        "02,50",
        "03,00",
        "02,00",
        "04,50",
        "02,50",
        "03,45",
        "01,50",
        "03,90",
        "07,00",
        "04,50"
};

int[] icones = new int[]{
    R.drawable.ic_coca_lata,
    R.drawable.ic_coca_zero_lata,
    R.drawable.ic_fanta_uva_lata,
    R.drawable.ic_guarana_antartica_lata,
    R.drawable.ic_guarana_antartica_zero_lata,
    R.drawable.ic_sukita_uva_lata,
    R.drawable.ic_sukita_laranja_lata,
    R.drawable.ic_sprite_lata,
    R.drawable.ic_guarana_antartica_pet,
    R.drawable.ic_sukita_uva_pet
};

private OnFragmentInteractionListener mListener;

public RefrigeranteFragment() {
    // Required empty public constructor
}

// TODO: Rename and change types and number of parameters
public static RefrigeranteFragment newInstance(String param1, String param2) {
    RefrigeranteFragment fragment = new RefrigeranteFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }
}

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

    List<HashMap<String, String>> aList = new ArrayList<HashMap<String, String>>();

    for (int i = 0; i < 10; i++){
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("txtNome", refrigerantes[i]);
        hm.put("txtPreco", precos[i]);
        hm.put("img_refrigerante", Integer.toString(icones[i]));
        aList.add(hm);
    }

    String[] from = {"img_refrigerante", "txtNome", "txtPreco"};
    int[] to = {R.id.img_refrigerante, R.id.txtNome, R.id.txtPreco};

    SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(), aList, R.layout.listview_refrigerante_layout, from, to);
    setListAdapter(adapter);
    // Inflate the layout for this fragment
    return super.onCreateView(inflater, container, savedInstanceState);
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onListItemClick(ListView listView, View view, int position, long id){
    super.onListItemClick(listView, view, position, id);

    final View v = view;

    final TextView txt = (TextView)view.findViewById(R.id.txtNome);
    final ImageView imageView = (ImageView)view.findViewById(R.id.img_refrigerante);
    final TextView tvQuantity = (TextView)view.findViewById(R.id.txtQtde);
    final TextView lblQuantity = (TextView)view.findViewById(R.id.lblQtde);
    final NumberPicker txtQtde = new NumberPicker(getContext());

    txtQtde.setMinValue(1);
    txtQtde.setMaxValue(10);

    if(tvQuantity.getText() != "")
        txtQtde.setValue(Integer.parseInt(tvQuantity.getText().toString()));

    AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
    builder.setTitle(txt.getText());
    builder.setMessage("Informe a quantidade");
    builder.setIcon(imageView.getDrawable());

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.MATCH_PARENT);

    txtQtde.setLayoutParams(lp);

    builder.setView(txtQtde);

    builder.setPositiveButton("Ok",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    tvQuantity.setText(String.valueOf(txtQtde.getValue()));
                    tvQuantity.setVisibility(View.VISIBLE);
                    lblQuantity.setVisibility(View.VISIBLE);

                    v.setBackgroundColor(Color.parseColor("#FF9933"));

                    ((TextView)v.findViewById(R.id.lblNome)).setTextColor(Color.WHITE);
                    ((TextView)v.findViewById(R.id.txtNome)).setTextColor(Color.WHITE);
                    ((TextView)v.findViewById(R.id.lblPreco)).setTextColor(Color.WHITE);
                    ((TextView)v.findViewById(R.id.txtPreco)).setTextColor(Color.WHITE);
                    ((TextView)v.findViewById(R.id.lblQtde)).setTextColor(Color.WHITE);
                    ((TextView)v.findViewById(R.id.txtQtde)).setTextColor(Color.WHITE);
                }

            });

    builder.setNegativeButton("Cancelar",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            }
    );

    builder.show();

}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
}

}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingLeft="8dp"
    android:paddingRight="8dp">

    <ImageView
        android:id="@+id/img_refrigerante"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/pizza_fragment"
        android:paddingRight="10dp"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:src="@drawable/ic_menu_pizza2" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_below="@+id/img_refrigerante" >

        <TextView
            android:id="@+id/lblNome"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Refrigerante: "
            android:textStyle="bold"
            android:textSize="15dp"
            android:layout_below="@id/img_pizza" />

        <TextView
            android:id="@+id/txtNome"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="15dp"
            android:layout_toRightOf="@+id/lblNome" />

        <TextView
            android:id="@+id/lblPreco"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Preço: "
            android:textStyle="bold"
            android:textSize="15dp"
            android:layout_below="@+id/txtNome" />

        <TextView
            android:id="@+id/txtPreco"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="15dp"
            android:layout_toRightOf="@+id/lblPreco"
            android:layout_below="@+id/txtNome" />

        <TextView
            android:id="@+id/lblQtde"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Qtde.: "
            android:textStyle="bold"
            android:textSize="15dp"
            android:visibility="invisible"
            android:layout_below="@+id/txtPreco" />

        <TextView
            android:id="@+id/txtQtde"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="15dp"
            android:visibility="invisible"
            android:layout_toRightOf="@+id/lblQtde"
            android:layout_below="@+id/txtPreco" />

    </RelativeLayout>

</RelativeLayout>

发生这种情况是因为 ListView 内的视图回收。

要使其正常工作,您需要三样东西:

  • 您的适配器中需要变量来存储项目的 "clicked" 状态;例如,布尔值列表。

  • 在你的onListItemClick()中,你需要在适配器上调用一个方法来改变当前项的状态并调用notifyDataSetChanged().

  • 在您的 getView() 覆盖中,您需要检查此状态并相应地设置正在创建的视图的背景。


这是一个适配器的代码(内部 class 用于您的 activity),它会记住一个项目是否被点击(以及数量):

    public static class MyListAdapter extends BaseAdapter {

        private String[] mNames;

        private String[] mPrices;

        private int[] mIcons;

        private int[] mQtys;

        private boolean[] mClicked;

        public MyListAdapter(String[] names, String[] prices, int[] icons) {
            mNames = names;
            mPrices = prices;
            mIcons = icons;
            mQtys = new int[names.length];
            mClicked = new boolean[names.length];
        }

        @Override
        public int getCount() {
            return mNames.length;
        }

        @Override
        public Object getItem(int position) {
            return mNames[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

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

            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_refrigerante_layout, parent, false);
            }

            ImageView icon = (ImageView) convertView.findViewById(R.id.img_refrigerante);
            icon.setImageResource(mIcons[position]);

            TextView name = (TextView) convertView.findViewById(R.id.txtNome);
            name.setText(mNames[position]);

            TextView price = (TextView) convertView.findViewById(R.id.txtPreco);
            price.setText(mPrices[position]);

            // hide these if qty == 0
            TextView qty = (TextView) convertView.findViewById(R.id.txtQtde);
            qty.setText(mQtys[position]);
            qty.setVisibility(mQtys[position] == 0 ? View.INVISIBLE : View.VISIBLE);

            TextView qtyLbl = (TextView) convertView.findViewById(R.id.lblQtde);
            qtyLbl.setVisibility(mQtys[position] == 0 ? View.INVISIBLE : View.VISIBLE);

            // here is where we use the clicked flag to determine which colors to set
            // TODO put a real color for backgroundColorNormal because I don't know what your normal background color is
            int backgroundColor = mClicked[position] ? Color.parseColor("#FF9933") : backgroundColorNormal;
            convertView.setBackgroundColor(backgroundColor);

            // TODO put a real color for colorNormal because I don't know what your normal text color is
            int textColor = mClicked[position] ? Color.WHITE : colorNormal;
            ((TextView) convertView.findViewById(R.id.lblNome)).setTextColor(textColor);
            ((TextView) convertView.findViewById(R.id.txtNome)).setTextColor(textColor);
            ((TextView) convertView.findViewById(R.id.lblPreco)).setTextColor(textColor);
            ((TextView) convertView.findViewById(R.id.txtPreco)).setTextColor(textColor);
            ((TextView) convertView.findViewById(R.id.lblQtde)).setTextColor(textColor);
            ((TextView) convertView.findViewById(R.id.txtQtde)).setTextColor(textColor);

            return convertView;
        }

        public int getQty(int position) {
            return mQtys[position];
        }

        public void setQty(int position, int qty) {
            mQtys[position] = qty;
            notifyDataSetChanged();
        }

        public void setClicked(int position, boolean clicked) {
            mClicked[position] = clicked;
            notifyDataSetChanged();
        }
    }

当您更改点击标志或数量时,将调用 notifyDataSetChanged()。这就是告诉 ListView 通过 getView() 再次向适配器询问项目视图,并且使用新值更新项目视图。

您需要在 activity:

中保留对此适配器的引用
    private MyListAdapter mAdapter;

并设置它:

    mAdapter = new MyListAdapter(refrigerantes, precos, icones);
    setListAdapter(mAdapter);

然后您的项目点击处理程序将如下所示(我稍微简化了它)

    @Override
    public void onListItemClick(ListView listView, View view, final int position, long id){
        super.onListItemClick(listView, view, position, id);

        final NumberPicker txtQtde = new NumberPicker(getContext());

        txtQtde.setMinValue(1);
        txtQtde.setMaxValue(10);
        txtQtde.setValue(Integer.parseInt(mAdapter.getQty(position)));

        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setTitle(refrigerantes[position]);
        builder.setMessage("Informe a quantidade");
        builder.setIcon(icones[position]);

        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);

        txtQtde.setLayoutParams(lp);

        builder.setView(txtQtde);

        builder.setPositiveButton("Ok",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mAdapter.setQty(position, txtQtde.getValue());
                        mAdapter.setClicked(position);
                    }

                });

        builder.setNegativeButton("Cancelar",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                }
        );

        builder.show();

    }

请 -- 做的不仅仅是 copy/paste 这件事,花时间逐行​​浏览代码以了解它是如何工作的。看示例代码是学习Android的好方法,但是如果copy/paste不理解就什么也学不到。

在此 link 中,我展示了如何更改 AlertDialog 中的项目背景颜色。它还展示了如何自定义 AletDialog。例如,如何更改分隔符颜色等。请访问此link:

希望对您有所帮助。