首页 > 解决方案 > classcastexception - 尝试实现 toptoche searchablespinner

问题描述

在我以前的应用程序中,我使用了 toptoche 依赖项的可搜索微调器。(我以前的应用程序与这个非常相似,只是使用了 recyclerview 和 cardviews)所以我检查了我的代码,只是用 SearchableSpinner 替换了 Spinner 对象。但是,当我运行应用程序并按下 FAB 时(假设显示 cardview 时),我得到了一个 classcastexception。我在这里错过了什么吗?

错误

java.lang.ClassCastException: android.support.v7.widget.AppCompatSpinner cannot be cast to com.toptoche.searchablespinnerlibrary.SearchableSpinner
        at com.app.supermarketaislefinder.ProductAdapter$ProductViewHolder.<init>(ProductAdapter.java:91)
        at com.app.supermarketaislefinder.ProductAdapter.onCreateViewHolder(ProductAdapter.java:41)
        at com.app.supermarketaislefinder.ProductAdapter.onCreateViewHolder(ProductAdapter.java:20)
        at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6685)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5869)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748)
        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2232)
        at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1559)
        at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
        at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:614)
        at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812)
        at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3529)
        at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:948)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1855)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:443)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1655)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1513)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1426)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
        at android.view.View.layout(View.java:13856)
        at android.view.ViewGroup.layout(ViewGroup.java:4424)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1992)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1813)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1113)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4481)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
        at android.view.Choreographer.doCallbacks(Choreographer.java:555)
        at android.view.Choreographer.doFrame(Choreographer.java:525)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4867)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
        at dalvik.system.NativeStart.main(Native Method)

ProductAdapter.java错误似乎在哪里

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {


    //this context we will use to inflate the layout
    private Context mCtx;
    private SearchableSpinner spinner;

    //we are storing all the products in a list
    private List<Product> productList;

    //getting the context and product list with constructor
    public ProductAdapter(Context mCtx, List<Product> productList) {
        this.mCtx = mCtx;
        this.productList = productList;
    }

    @Override
    public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //inflating and returning our view holder
        LayoutInflater inflater = LayoutInflater.from(mCtx);
        View view = inflater.inflate(R.layout.layout_products, null);
        return new ProductViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ProductViewHolder holder, int position) {
        //getting the product of the specified position
        Product product = productList.get(position);

        //binding the data with the viewholder views


        //MyListAdapter adapter = new MyListAdapter(mCtx, R.layout.listrow, R.id.txtid, Product.spinnerItemsList);
        //spinner.setAdapter(adapter);

        ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String> (mCtx, android.R.layout.simple_spinner_item, Product.getSpinnerItemsList());
        spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        holder.spinner.setAdapter(spinnerArrayAdapter);
    }


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



    class ProductViewHolder extends RecyclerView.ViewHolder {

        SearchableSpinner spinner;
        EditText editText;
        TextView textView5;
        CheckBox checkBox;



        public ProductViewHolder(View itemView) {
            super(itemView);

            spinner = itemView.findViewById(R.id.spinner);
            editText = itemView.findViewById(R.id.editText);
            textView5 = itemView.findViewById(R.id.textView5);
            checkBox = itemView.findViewById(R.id.checkBox);
        }
    }
}

和我的活动代码供参考

public class create extends AppCompatActivity {



    //a list to store all the products
    List<Product> productList;

    //the recyclerview
    RecyclerView recyclerView;

    Product mProduct;
    private Map<String, String> numberItemValues = new HashMap<>();




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

        //opens csv
        InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
         CSVFile csvFile = new CSVFile(inputStream);

       final List<String>  mSpinnerItems = csvFile.read();


        //getting the recyclerview from xml
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        //initializing the productlist
        productList = new ArrayList<>();

///s/Di it work?
        //I click the dropdown and the items show! I select an item, then i press fab to get another cardview
        //I select an item from there , it shows
        //i add another cardview then all the spinners are cleared?
        //Hmm its because when the recyclerview item is out of the screen scope its recycled now you need to find a solution of
        //storing the state of spinner for selected item
        //i had a previous app which did exactly the same as this just without recyclerview and cardview. but with spinner i think
        //i used sharedpreferences or something. i can have a look at my old code and see


        //I will suggest you to make an array and then store the selected item by the index of the item in recyclerview





      final SearchableSpinner spinner;
      final EditText editText;
      final CheckBox checkBox;
      final TextView textView5;

      spinner = findViewById(R.id.spinner);
      editText = findViewById(R.id.editText);
      checkBox = findViewById(R.id.checkBox);
      textView5 = findViewById(R.id.textView5);

      final ProductAdapter  adapter = new ProductAdapter(this, productList);

        //TODO FAB BUTTON
        FloatingActionButton floatingActionButton =
                (FloatingActionButton) findViewById(R.id.fab);


        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                List<Product> mProductList = new ArrayList<>();
                productList.add(mProduct);
                if(adapter != null)
                    adapter.notifyDataSetChanged();
                //Handle the empty adapter here

            }
        });


       /* //TODO Add the spinner on item selected listener to get selected items
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                String currentItem = mSpinnerItems.get(position);
                String aisleNumber = numberItemValues.get(currentItem);
                //TODO you can use the above aisle number to add to your text view
                //mTextviews.get(mTextviews.size() -1).setText(aisleNumber);
                textView5.setText(aisleNumber);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parentView) {
                //  do nothing
            }
        });*/






        //setting adapter to recyclerview
        recyclerView.setAdapter(adapter);






    }




    private class CSVFile {
        InputStream inputStream;

        public CSVFile(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        public List<String> read() {
// The problem with your adapter is solved now you need to do some work here its giving an error while reading the file
            //why is it giving an error because it use to work fine before I added cardview and recyclerview
            //Is the file there?
            List<String> resultList = new ArrayList<String>();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                String line;
                while ((line = reader.readLine()) != null) {
                    String[] row = line.split(",");
                    //TODO I edited this part so that you'd add the values in our new hash map variable

                    numberItemValues.put(row[1], row[0]);

                    resultList.add(row[1]);
                }
            } catch (IOException e) {
                Log.e("Main", e.getMessage());
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    Log.e("Main", e.getMessage());
                }
            }
            return resultList;
        }
    }



}

标签: android

解决方案


问题是当您的 Spinner 对象存在于您的适配器中时,您正在 Activity 中执行操作,因此有两种方法,一种是从 Activity 内部的适配器访问该项目,一种是在 AdapterView 中实现该方法。

public class create extends AppCompatActivity {



    //a list to store all the products
    List<Product> productList;

    //the recyclerview
    RecyclerView recyclerView;

    Product mProduct;
    private Map<String, String> numberItemValues = new HashMap<>();




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

        //opens csv
        InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
         CSVFile csvFile = new CSVFile(inputStream);

       final List<String>  mSpinnerItems = csvFile.read();


        //getting the recyclerview from xml
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        //initializing the productlist
        productList = new ArrayList<>();

      final ProductAdapter  adapter = new ProductAdapter(this, productList);

        //TODO FAB BUTTON
        FloatingActionButton floatingActionButton =
                (FloatingActionButton) findViewById(R.id.fab);


        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                List<Product> mProductList = new ArrayList<>();
                productList.add(mProduct);
                if(adapter != null)
                    adapter.notifyDataSetChanged();
                //Handle the empty adapter here

            }
        });







        //setting adapter to recyclerview
        recyclerView.setAdapter(adapter);






    }




    private class CSVFile {
        InputStream inputStream;

        public CSVFile(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        public List<String> read() {
// The problem with your adapter is solved now you need to do some work here its giving an error while reading the file
            //why is it giving an error because it use to work fine before I added cardview and recyclerview
            //Is the file there?
            List<String> resultList = new ArrayList<String>();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                String line;
                while ((line = reader.readLine()) != null) {
                    String[] row = line.split(",");
                    //TODO I edited this part so that you'd add the values in our new hash map variable

                    numberItemValues.put(row[1], row[0]);

                    resultList.add(row[1]);
                }
            } catch (IOException e) {
                Log.e("Main", e.getMessage());
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    Log.e("Main", e.getMessage());
                }
            }
            return resultList;
        }
    }



}

推荐阅读