无法将FrameLayout强制转换为AbsListView布局参数

时间:2019-07-18 19:54:57

标签: java android android-arrayadapter android-framelayout layoutparams

我有一个奇怪的问题,我有下一个代码文件:

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;
    }
}

以及当我使用 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;
            }
        }
    }
}

错误崩溃:

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

我在为ListView设置适配器时遇到了一个奇怪的问题,该ListView在自定义键盘的CandidateView内部,我使用继承AsyncTask类的类来执行API调用,该调用返回给我要列出的项目显示在ListView上,在AsyncTask的onPostExecute()方法中,我将搜索结果添加到ArrayList中,然后使用方法updateResults()将此数组传递给适配器,最后设置ListView的适配器,一切都很好直到这里,代码都可以编译,但是在运行时我遇到了下一个错误:

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

请帮忙吗?如何解决?

非常感谢您的光临

2 个答案:

答案 0 :(得分:1)

就我所知,在设置适配器后几次错误发生在ListView内部,这是一个很复杂的问题,要考虑到崩溃的代码行,也很难解决在没有Android Studio或编译器警告的情况下将其弄错了,所以我的建议是使用RecyclerView代替ListViewRecyclerView是{{1}的更高级,更灵活的版本},易于实现,而且我敢肯定,它将在应用程序中解决您的问题。 Follow this link,您将找到一个很好的示例,说明如何实现ListView

答案 1 :(得分:0)

如我所见,此问题可能来自错误的LayoutParamsListView实现期望AbsListView.LayoutParams而不是FrameLayout.LayoutParams。我想您的布局之一(source_cell.xmlbid_cell.xml)有一个FrameLayout作为根视图。这不是问题,但是您可以修正充气方法以获得正确的LayoutParams

getView()方法内的 bidAdapter.java 中进行以下更改:

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

对此:

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

此通货膨胀程序将知道候选父级将在何处放置通货膨胀视图。这使它可以使用适当的LayoutParam进行膨胀。下一个false参数将阻止自动添加子视图。 (因为ListView实现将在以后添加)