在片段中调用接口方法会抛出ClassCastException异常。

3
这是我代码中有问题的那一行:

listAdapter.setCustomButtonListener((CustomButtonListener) getActivity());**

这个监听器在AppCompatActivity中完美运作,但当我尝试在片段中使用它时,会抛出ClassCastException异常。以下是日志记录:

日志记录:

FATAL EXCEPTION: main  Process: info.tranetech.laundry, PID: 21707
                                                                        java.lang.ClassCastException: info.tranetech.laundry.pricelist.ItemListTab cannot be cast to tranetech.laundry.pricelist.CustomButtonListener
                                                                            at info.tranetech.laundry.pricelist.ManItems$GetContacts.onPostExecute(ManItems.java:177)
                                                                            at info.tranetech.laundry.pricelist.ManItems$GetContacts.onPostExecute(ManItems.java:98)
                                                                            at android.os.AsyncTask.finish(AsyncTask.java:632)
                                                                            at android.os.AsyncTask.access$600(AsyncTask.java:177)
                                                                            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                            at android.os.Looper.loop(Looper.java:146)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:5748)
                                                                            at java.lang.reflect.Method.invokeNative(Native Method)
                                                                            at java.lang.reflect.Method.invoke(Method.java:515)
                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
                                                                            at dalvik.system.NativeStart.main(Native Method)

这是我的接口。
CustomButtonListener.java
public interface CustomButtonListener {
    public void onButtonClickListener(int position, EditText editText, int value);
}

这里是您的TabBar(AppCompatActivity)。
项目列表选项卡.java
public class ItemListTab extends AppCompatActivity {

    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private int[] tabIcons = {
            R.drawable.ic_tab_favourite,
            R.drawable.ic_tab_call,
            R.drawable.ic_tab_contacts
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.item_list_tabs);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);

        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
        setupTabIcons();
    }

    private void setupTabIcons() {
        tabLayout.getTabAt(0).setIcon(tabIcons[0]);
        tabLayout.getTabAt(1).setIcon(tabIcons[1]);
        tabLayout.getTabAt(2).setIcon(tabIcons[2]);
        tabLayout.getTabAt(3).setIcon(tabIcons[0]);
    }

    private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFrag(new ManItems(), "");
        adapter.addFrag(new WomanItems(), "");
        adapter.addFrag(new KidItems(), "");
        adapter.addFrag(new HouseHoldItems(), "");
        viewPager.setAdapter(adapter);
    }

    class ViewPagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        public void addFrag(Fragment fragment, String title) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }
    }
}

这是我的Fragment,在其中调用了listAdapter.setCustomButtonListener((CustomButtonListener) getActivity());
ManItems.java
   public class ManItems extends Fragment implements CustomButtonListener{

    private ListView listView;
    View rootView;
    Context context;
    private ListAdapter listAdapter;
    public static String[] ItemName, prices,ItemImage;
    Button PlaceOrder;
    ProgressDialog pDialog;
    HashMap<String, String> itemMap;
    // Hashmap for ListView
    ArrayList<HashMap<String, String>> ItemList = new ArrayList<HashMap<String, String>>();


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

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        rootView = inflater.inflate(R.layout.content_main, container, false);

        listView = (ListView) rootView.findViewById(R.id.customListView);
        PlaceOrder = (Button) rootView.findViewById(R.id.place_order);

        // Calling async task to get json
        new GetContacts().execute();


        PlaceOrder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (ListAdapter.map.isEmpty()) {
                    Toast.makeText(getActivity(), "Please select items", Toast.LENGTH_SHORT).show();
                } else {
                    ListAdapter.map.values().removeAll(Collections.singleton("0"));
                    Intent intent = new Intent(getActivity(), OrderList.class);
                    startActivity(intent);
                }
            }
        });

        return  rootView;
    }

    @Override
    public void onButtonClickListener(int position, EditText editText, int value) {
        //  View view = listView.getChildAt(position);
        int quantity = Integer.parseInt(editText.getText().toString());

        quantity = quantity + 1 * value;
        if (quantity < 0)
            quantity = 0;
        editText.setText(quantity + "");

    }

    /**
     * Async task class to get json by making HTTP call
     */
    private class GetContacts extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Please wait...");
            pDialog.setCancelable(false);
            pDialog.show();

        }

        @Override
        protected Void doInBackground(Void... arg0) {
            // Creating service handler class instance
            JSONParser JP = new JSONParser();

            // Making a request to url and getting response
            String jsonStr = JP.makeServiceCall("http://openspace.tranetech.com/mis/Laundry/items.php", JSONParser.GET);

            Log.d("Response: ", "> " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject jsonObj = new JSONObject(jsonStr);

                    // Getting JSON Array node
                    JSONArray itmeArray = jsonObj.getJSONArray("Data");

                    ItemName = new String[itmeArray.length()];
                    prices = new String[itmeArray.length()];
                    ItemImage = new String[itmeArray.length()];

                    // looping through All Contacts
                    for (int i = 0; i < itmeArray.length(); i++) {
                        JSONObject item = itmeArray.getJSONObject(i);

                        String price = item.getString("price").toString();
                        String name = item.getString("item_name").toString();
                        String image = item.getString("image").toString();

                        ItemName[i] = name;
                        prices[i] = price;
                        ItemImage[i] =image;

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                Log.e("ServiceHandler", "Couldn't get any data from the url");
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            if (pDialog.isShowing()) {

                for (int z = 0; z < ItemName.length; z++) {

                    Log.d("Name  ", "" + ItemName[z]);
                    Log.d("Price ", "" + prices[z]);
                    Log.d("Images ", "" + ItemImage[z]);
                }
                pDialog.dismiss();

            }
//            images = getResources().obtainTypedArray(R.array.ProductImages);

            /**
             * Updating parsed JSON data into ListView
             * */
            listAdapter = new ListAdapter(getActivity(), ItemName, ItemImage, prices);
            listView.setAdapter(listAdapter);
            listAdapter.setCustomButtonListener((CustomButtonListener) getActivity());

        }
    }


}

更改后的代码:listAdapter.setCustomButtonListener(ManItems.this);

日志记录(Logcat):

     java.lang.NullPointerException
                                                                            at info.tranetech.laundry.pricelist.ListAdapter.getView(ListAdapter.java:95)
                                                                            at android.widget.AbsListView.obtainView(AbsListView.java:2768)
                                                                            at android.widget.ListView.makeAndAddView(ListView.java:1817)
                                                                            at android.widget.ListView.fillDown(ListView.java:703)
                                                                            at android.widget.ListView.fillFromTop(ListView.java:769)
                                                                            at android.widget.ListView.layoutChildren(ListView.java:1647)
                                                                            at android.widget.AbsListView.onLayout(AbsListView.java:2586)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1692)
                                                                            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1534)
                                                                            at android.widget.LinearLayout.onLayout(LinearLayout.java:1443)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1627)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1034)
                                                                            at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:744)
                                                                            at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
                                                                            at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1180)
                                                                            at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:757)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
                                                                            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1692)
                                                                            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1534)
                                                                            at android.widget.LinearLayout.onLayout(LinearLayout.java:1443)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
                                                                            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1692)
                                                                            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1534)
                                                                            at android.widget.LinearLayout.onLayout(LinearLayout.java:1443)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
                                                                            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
                                                                            at android.view.View.layout(View.java:15903)
                                                                            at android.view.ViewGroup.layout(ViewGroup.java:4932)
                                                                            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2418)
                                                                            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2133)
                                                                            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1297)
                                                                            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6773)
                                                                            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:813)
                                                                            at android.view.Choreographer.doCallbacks(Choreographer.java:613)
                                                                            at android.view.Choreographer.doFrame(Choreographer.java:583)
                                                                            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:799)
                                                                            at android.os.Handler.handleCallback(Handler.java:733)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                            at android.os.Looper.loop(Looper.java:146)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:5748)
                                                                            at java.lang.reflect.Method.invokeNative(Native Method)
                                                                            at java.lang.reflect.Method.invoke(Method.java:515)
                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)

  [1]: https://www.vlemonn.com/Blog/Android/Android-Custom-ListView-with-ImageView-EditText-and-Button/

错误定位

for (int z = 0; z < MainActivity_items.ItemImage.length; z++) {

            Picasso.with(context)
                    .load(""+MainActivity_items.ItemImage[position])
                    .into(listViewHolder.ivProduct);
        }

ListAdapter.java

public class ListAdapter extends BaseAdapter {

    public ArrayList<Integer> quantity = new ArrayList<Integer>();
    public ArrayList<Integer> price = new ArrayList<Integer>();
    private String[] listViewItems, prices, static_price;
    String[] images;
    View row = null;

    static String get_price, get_quntity;
    int g_quntity, g_price, g_minus;

    private Context context;
    CustomButtonListener customButtonListener;

    static HashMap<String, Integer> map = new HashMap<>();


    public ListAdapter(Context context, String[] listViewItems, String[] images, String[] prices) {
        this.context = context;
        this.listViewItems = listViewItems;
        this.images = images;
        this.prices = prices;

        for (int i = 0; i < listViewItems.length; i++) {
            quantity.add(0);
        }
    }

    public void setCustomButtonListener(CustomButtonListener customButtonListner) {
        this.customButtonListener = customButtonListner;
    }

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

    @Override
    public String getItem(int position) {
        return listViewItems[position];
    }


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

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

        final ListViewHolder listViewHolder;
        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = layoutInflater.inflate(R.layout.activity_custom_listview, parent, false);
            listViewHolder = new ListViewHolder();
            listViewHolder.tvProductName = (TextView) row.findViewById(R.id.tvProductName);
            listViewHolder.ivProduct = (ImageView) row.findViewById(R.id.ivproduct);
            listViewHolder.tvPrices = (TextView) row.findViewById(R.id.tvProductPrice);
            listViewHolder.btnPlus = (ImageButton) row.findViewById(R.id.ib_addnew);
            listViewHolder.edTextQuantity = (EditText) row.findViewById(R.id.editTextQuantity);
            listViewHolder.btnMinus = (ImageButton) row.findViewById(R.id.ib_remove);
            static_price = context.getResources().getStringArray(R.array.Price);
            row.setTag(listViewHolder);
        } else {
            row = convertView;
            listViewHolder = (ListViewHolder) convertView.getTag();
        }

        //Loading image from below url into imageView

for (int z = 0; z < MainActivity_items.ItemImage.length; z++) {
    Picasso.with(context)
           .load(""+MainActivity_items.ItemImage[position])
           .into(listViewHolder.ivProduct);
}

//      listViewHolder.ivProduct.setImageResource(images.getResourceId(position, -1));
        listViewHolder.edTextQuantity.setText(quantity.get(position) + "");
        listViewHolder.tvProductName.setText(listViewItems[position]);
        listViewHolder.tvPrices.setText(prices[position]);


        listViewHolder.btnPlus.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (customButtonListener != null) {
                    customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, 1);

                    quantity.set(position, quantity.get(position) + 1);
                    //price.set(position, price.get(position) + 1);

                    row.getTag(position);

                    get_price = listViewHolder.tvPrices.getText().toString();

                    g_price = Integer.valueOf(static_price[position]);

                    get_quntity = listViewHolder.edTextQuantity.getText().toString();
                    g_quntity = Integer.valueOf(get_quntity);

                    Integer.parseInt(listViewHolder.edTextQuantity.getText().toString());
                    map.put("" + listViewHolder.tvProductName.getText().toString(), Integer.valueOf(Integer.parseInt(listViewHolder.edTextQuantity.getText().toString())));
//                    Log.d("A ", "" + a);
//                    Toast.makeText(context, "A" + a, Toast.LENGTH_LONG).show();
//                    Log.d("Position ", "" + position);
//                    System.out.println(+position + " Values " + map.values());
                    listViewHolder.tvPrices.getTag();
                    listViewHolder.tvPrices.setText("" + g_price * g_quntity);
                    ShowHashMapValue();

                }


            }

        });
        listViewHolder.btnMinus.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (customButtonListener != null) {

                    customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, -1);
                    if (quantity.get(position) > 0)
                        quantity.set(position, quantity.get(position) - 1);

                    get_price = listViewHolder.tvPrices.getText().toString();
                    g_minus = Integer.valueOf(get_price);
                    g_price = Integer.valueOf(static_price[position]);
                    int minus = g_minus - g_price;
                    if (minus >= g_price) {
                        listViewHolder.tvPrices.setText("" + minus);
                    }
                    map.put("" + listViewHolder.tvProductName.getText().toString(), Integer.valueOf(Integer.parseInt(listViewHolder.edTextQuantity.getText().toString())));
                    ShowHashMapValue();
                }
            }
        });


        return row;
    }

    private void ShowHashMapValue() {
        /**
         * get the Set Of keys from HashMap
         */
        Set setOfKeys = map.keySet();

/**
 * get the Iterator instance from Set
 */
        Iterator iterator = setOfKeys.iterator();

/**
 * Loop the iterator until we reach the last element of the HashMap
 */
        while (iterator.hasNext()) {
/**
 * next() method returns the next key from Iterator instance.
 * return type of next() method is Object so we need to do DownCasting to String
 */
            String key = (String) iterator.next();

/**
 * once we know the 'key', we can get the value from the HashMap
 * by calling get() method
 */
            int value = map.get(key);

            System.out.println("Key: " + key + ", Value: " + value);
        }
    }
}

这个错误是因为你的活动没有实现接口。如果你想让活动处理回调,那么活动应该实现接口。在你的情况下,通过将listAdapter.setCustomButtonListener((CustomButtonListener) getActivity()); 更改为listAdapter.setCustomButtonListener(ManItems.this),可以解决你的问题,因为我注意到你的片段已经实现了接口,我假设它是片段处理回调。 - kopikaokao
3个回答

1
正如错误所述,ItemListTab活动无法转换为CustomButtonListener,因为它没有实现它,《当前片段》已经实现了。因此您需要进行更改。
listAdapter.setCustomButtonListener((CustomButtonListener) getActivity());

listAdapter.setCustomButtonListener(ManItems.this);
/* Not listAdapter.setCustomButtonListener(this), otherwise
 you would be referring to the AsyncTask 'GetContacts' itself */

谢谢回复。这意味着我不能在片段中实现吗? - Arpit Patel
当然可以,只需按照我说的更改上面的那一行,你就可以顺利进行了。 - Mohammed Aouf Zouag
其实 @ArpitPatel ,你的问题在技术上已经解决了。你现在遇到的问题与实际问题没有任何关系。此外,我无法从logcat中看出错误是什么以及如何修复它。所以你需要就这个问题提出一个新的问题,并确保你只发布与该问题相关的代码,以便社区能够更好地帮助你。 - Mohammed Aouf Zouag
在 getView() 中发现错误,需替换 MainActivity_items = ManItem。非常感谢您的帮助,你让我的一天变得美好。 - Arpit Patel

0
希望这能帮到你。 在片段中使用接口监听器时, 不要在片段类上实现,而是在选项卡活动中实现监听器。 并且片段的图像视图或任何内容都应该是公共静态的。

0

如果你正在使用 getActivity(),你的 Activity ItemListTab 必须实现 CustomButtonListener 接口

将 ManItems 的引用传递,因为 ManItems 已经实现了 CustomButtonListener 接口


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接