简体   繁体   中英

FrameLayout cannot be cast to AbsListView Layout Params

I have an strange issue I have the nexts code files:

result_suggestion.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/result_suggestion_container"
    android:orientation="vertical"
    android:background="#fff">
    <!--android:visibility="gone"-->

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/result_list"
        android:scrollbars="vertical" />

</LinearLayout>

results_suggestions_footer.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:background="#e6e9ea">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="250dp"
        android:layout_marginTop="10dp"
        android:contentDescription="@string/results_suggestion_footer"
        app:srcCompat="@drawable/ic_baseline_search_24px" />

    <Button
        android:id="@+id/keep_searching"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/search_button"
        android:text="@string/quotes_suggestion_footer" />

    <!--android:drawableEnd="@drawable/ic_baseline_search_24px"-->

</RelativeLayout>

bidAdapter.java:

package com.my.app.ui.adapters;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.my.app.R;
import com.my.app.api.models.sonnet;
import com.my.app.api.models.sonnetbid;
import com.my.app.api.interfaces.SuggestionListItem;

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

import javax.security.auth.login.LoginException;

/**
 * Class of the custom adapter for the suggestions list of bids.
 *
 * @author Dennis Mostajo on 1/18/18
 */

public class bidAdapter extends BaseAdapter {

    private static final int sonnet = 0;
    private static final int bid = 1;
    private List<SuggestionListItem> mSuggestions;
    private LayoutInflater mInflater;

    //===========================================================================
    //                             CONSTRUCTOR
    //===========================================================================

    /**
     * Custom constructor implementation in charge of the initialization of internal members
     *
     * @param context application context for the layout inflater initialization
     */
    public bidAdapter(Context context) {

        this.mSuggestions = new ArrayList<>();
        this.mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    //===========================================================================
    //                           OVERRIDE METHODS
    //===========================================================================

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

    @Override
    public Object getItem(int position) {
        return mSuggestions.get(position);
    }

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

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {

        if(mSuggestions.get(position).getInstanceType() == SuggestionListItem.InstanceType.sonnet) {
            return sonnet;
        } else {
            return bid;
        }
    }

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

        ViewHolder holder;
        int cellType = getItemViewType(position);

        if (convertView == null) {
            holder = new ViewHolder();

            switch(cellType) {
                case sonnet:
                    convertView = mInflater.inflate(R.layout.source_cell, null);
                    holder.mSource = convertView.findViewById(R.id.source);
                    holder.mSourceInformation = convertView.findViewById(R.id.source_information);
                    break;
                case bid:
                    convertView = mInflater.inflate(R.layout.bid_cell, null);
                    holder.mbid = convertView.findViewById(R.id.bid);
                    holder.mbidInformation = convertView.findViewById(R.id.bid_information);
                    break;
            }

            if (convertView != null) {
                convertView.setTag(holder);
            }

        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        switch (cellType) {
            case sonnet:
                holder.mSource.setText(((sonnet) mSuggestions.get(position)).getContent());
                holder.mSourceInformation.setText("");
                break;
            case bid:
                holder.mbid.setText(((sonnetbid) mSuggestions.get(position)).getText());
                sonnet sonnet = ((sonnetbid) mSuggestions.get(position)).getsonnet();
                String text = String.format("%s%s%s%s%s%s%s", " (", sonnet.getBook(), " ", sonnet
                        .getChapter(), ":", sonnet.getsonnetNumber(), ").");

                holder.mbidInformation.setText(text);

                break;
        }

        return convertView;
    }

    //===========================================================================
    //                         CUSTOM METHODS
    //===========================================================================

    /**
     * Method used to update the list of suggestions to be given to the user
     *
     * @param suggestions list containing suggested bids and stanzas
     */
    public void updateSuggestions(List<SuggestionListItem> suggestions) {

        if(suggestions != null) {
            this.mSuggestions.clear();
            this.mSuggestions = suggestions;
            this.notifyDataSetChanged();
        }
    }

    //===========================================================================
    //                           PRIVATE CLASSES
    //===========================================================================

    /**
     * Class for the implementation of the ViewHolder design pattern used to represent the bids
     * and stanzas cells.
     */
    private static class ViewHolder {
        private TextView mbid;
        private TextView mbidInformation;
        private TextView mSource;
        private TextView mSourceInformation;
    }
}

and when I using my keyboardIME :

    private View initInputView() {

        mCurrentTheme = ThemeManager.getInstance(this).getTheme();
        mKeyboardView.setKeyboard(mKeyboard);
        mKeyboardView.setOnKeyboardActionListener(this);

        mInflater = (LayoutInflater) this.getSystemService(Context
                .LAYOUT_INFLATER_SERVICE);

        mSuggestionsView = mInflater.inflate(R.layout.result_suggestion, null);
        mResultListFooter = mInflater.inflate(R.layout.results_suggestion_footer, null);

        initAlternativeCandidatesView();

        mResultList = mSuggestionsView.findViewById(R.id.result_list);
        mResultList.addFooterView(mResultListFooter);
        mResultsAdapter = new bidAdapter(this);
        mResultList.setAdapter(mResultsAdapter);
        mResultList.setOnItemClickListener((AdapterView<?> parent, View view, int position,
                                           long id) -> {

            SuggestionListItem item = (SuggestionListItem) mResultsAdapter
                    .getItem(position);
        });

        return mKeyboardView;
    }
 @Override
        protected void onPostExecute(SearchRequestResult result) {

            switch (result) {

                case SUCCESS:

                    if(mSonnetBidResult.size() > 0) {

                        List<SuggestionListItem> bidSonnetList = new ArrayList<>(
                                mSonnetBidResult);
                 mQuotesIME.get().mResultsAdapter.updateSuggestions(bisSonnetList);    
// the crash is here                        

mQuotesIME.get().mQuoteList.setAdapter(mQuotesIME.get().mResultsAdapter);// IMEKeyboard.java:2305
                 mQuotesIME.get().mResultsAdapter);

                        // Added by Dennis Try to fix Height of suggestions lists
                        if (mSonnetBidResult.size() > 2) {
                            mQuotesIME.get().maximize_quote_lists();
                        } else {
                            mQuotesIME.get().minimize_quote_lists();
                        }

                        mQuotesIME.get().setCandidatesView(mQuotesIME.get().mSuggestionsView);

                    } else {
                        mQuotesIME.get().updateWaitingCandidateView(mQuotesIME.get().getString(R
                                .string.no_results_label));
                    }
                    break;

                case ERROR:

                    try {
                        JSONObject jsonObject = new JSONObject(this.mErrorMessage);

                        int minLength = jsonObject.getInt("min_phrase_len");
                        if(minLength > 0) {
                            mQuotesIME.get().updateWaitingCandidateView(mQuotesIME.get().getString(
                                    R.string.length_error).replace("{int}", String.valueOf(
                                            minLength)));

                        } else {
                            mQuotesIME.get().updateWaitingCandidateView(mQuotesIME.get().getString(
                                    R.string.no_phrase_error));
                        }
                    } catch (JSONException e) {
                        Crashlytics.log("Error extracting message from /search call: "
                                + e.getMessage());
                        e.printStackTrace();
                    }
                    break;
            }
        }
    }
}

ERROR CRASH:

07-16 14:41:09.488 21099-21099/com.my.app D/AndroidRuntime: Shutting down VM
07-16 14:41:09.514 21099-21099/com.my.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.my.app, PID: 21099
    java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
        at android.widget.ListView.clearRecycledState(ListView.java:627)
        at android.widget.ListView.resetList(ListView.java:614)
        at android.widget.ListView.setAdapter(ListView.java:557)
        at com.my.app.services.IMEKeyboard$resultSearchAsyncTask.onPostExecute(IMEKeyboard.java:2305)
        at com.my.app.services.IMEKeyboard$resultSearchAsyncTask.onPostExecute(IMEKeyboard.java:2175)
        at android.os.AsyncTask.finish(AsyncTask.java:695)
        at android.os.AsyncTask.-wrap1(Unknown Source:0)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
07-16 14:41:11.786 21099-21151/com.my.app I/CrashlyticsCore: Crashlytics report upload complete: 5D2E1A3601BE-0001-526B-29AD77A5B0D7

I have a strange issue setting up an adapter for a ListView, the ListView is inside the CandidateView of a custom keyboard, I use a class that inherit of AsyncTask class to execute an API call that returns me a list of items to be displayed on a ListView, in the method onPostExecute() of AsyncTask I take the search results and add to an ArrayList, then this array is being passed to the adapter using the method updateResults(), and finally set the ListView's adapter, everything is fine until here, the code compiles, but during runtime I get the next error:

java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams

ANY HELP PLEASE?, how can I fix it?

Thank you very much for your time

As I see, this issue can come from the wrong LayoutParams . ListView implementation expects AbsListView.LayoutParams and not FrameLayout.LayoutParams . I guess, one of your layout ( source_cell.xml or bid_cell.xml ) has a FrameLayout as root view. This is not a problem but you would fix the inflation method to get proper LayoutParams .

Change this in bidAdapter.java inside of getView() method:

convertView = mInflater.inflate(R.layout.source_cell, null);

To this:

convertView = mInflater.inflate(R.layout.source_cell, parent, false);

This inflation procedure will know the candidate parent where inflated view would be placed. This allows it to inflate with proper LayoutParam . The next false parameter are going to prevent to add child view automatically. (Because ListView implementation will add later)

For all I can see the error occurs a few calls after setting the adapter and happen inside the ListView , this is a complicated issue to fix taking into account the line of code where is crashing, also is hard to get this wrong without a warning from Android Studio or the compiler, so my suggestion is to use RecyclerView instead of the ListView , RecyclerView is a more advanced and flexible version of ListView , is easy to implement and I'm pretty sure that will fix your issue in the app. Follow this link and you will find a good example on how to implement the RecyclerView .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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