【问题标题】:launching a DialogFragment within getView of a custom Adapter在自定义适配器的 getView 中启动 DialogFragment
【发布时间】:2017-02-12 15:53:59
【问题描述】:

我有一个自定义的Adapter,在它的getView() 方法中,当用户单击Button 时,我尝试启动一个警报对话框,但我收到错误消息。 我希望有人可以在这里帮助我

这是我的自定义适配器:

package com.example.android.testappsfeatures;

import android.content.Context;
import android.graphics.Color;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


/**
 * Created by korchix on 05.02.17.
 */

public class UserAdapter extends ArrayAdapter<UserCard> {

    Context context = getContext().getApplicationContext();    

    public UserAdapter(Context context, ArrayList<UserCard> userCards) {
        super(context, 0, userCards);
    }


    // override getView because where are using other view than just TV alone.
    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        // get the data item for this position
        final UserCard newUser = getItem(position);
        final ViewHolder holder = new ViewHolder();
        // check if an existing view is being reused, otherwise inflate the view
        if(convertView == null){
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.user_layout, parent, false);
        }

        View userCardbackgroundColor = convertView.findViewById(R.id.userCard);
        userCardbackgroundColor.setBackgroundColor(Color.WHITE);


        // Lookup view for data population
        holder.userNameTV = (TextView) convertView.findViewById(R.id.name_textView);
        holder.userNameTV.setText(newUser.getUserName());

        holder.gutHabenTV = (TextView) convertView.findViewById(R.id.guthaben_textView);
        holder.gutHabenTV.setText(NumberFormat.getCurrencyInstance().format(Double.parseDouble(newUser.getGuthaben())));

        holder.timeStampTV = (TextView) convertView.findViewById(R.id.datumUhrzeit_textVie);
        holder.timeStampTV.setText(newUser.getTimeStamp());

        holder.plusButton = (Button) convertView.findViewById(R.id.plusButton_Layout);
        holder.plusButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

         **// HERE IS THE PROBLEM**
                FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fm.beginTransaction();
                AddBalanceDialog addBalanceDialog = new AddBalanceDialog();
                fragmentTransaction.replace(R.id.containerLayoutID, addBalanceDialog);
                fragmentTransaction.commit();

            }
        });
        return convertView;
    }
}



class ViewHolder {
    TextView userNameTV;
    TextView gutHabenTV;
    TextView timeStampTV;
    Button plusButton;
    Button minusButton;
}

这是AlertDialog (DialogFragment)的代码

package com.example.android.testappsfeatures;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

/**
 * Created by korchix on 04.02.17.
 */

public class AddBalanceDialog extends DialogFragment {
    Context context;
    InputUserDataDialog inputUserDataDialog = new InputUserDataDialog();




    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        context = getActivity().getApplicationContext();
        //user Dialog class for convenient dialog construction
        AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
        // get the layoutInflater
        LayoutInflater inflater = getActivity().getLayoutInflater();
        // inflate our custom Layout for the dialog to a View
        View view = inflater.inflate(R.layout.add_guthaben, null);

        final TextView guthabenTV = (TextView) view.findViewById(R.id.guthaben_textView);

        final EditText addGuthabenET = (EditText) view.findViewById(R.id.add_guthaben_LayoutET);

        // inform the dialog it has a custom View
        dialog.setView(view);

        // when positiv button clicked
        dialog.setPositiveButton(R.string.dialog_ok_buttom, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String input = addGuthabenET.getText().toString();

               guthabenTV.setText(input);


                // hier muss noch was
                // gemacht werden
            }
        })
                .setNegativeButton(R.string.dialog_cancel_button, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // discard the input -> don't make any change
                        dialog.cancel();

                    }
                });

        return dialog.create();
    }

}

点击plusButton.setOnClickListener(new View.OnClickListener()时出现此错误

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                      Process: com.example.android.testappsfeatures, PID: 30548
java.lang.ClassCastException: android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity
at com.example.android.testappsfeatures.UserAdapter$1.onClick(UserAdapter.java:83)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我在这里读到的问题似乎与上下文有关,我给Application Context,但我应该给Activity context。我不知道该怎么做。

这是我的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.testappsfeatures">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".InputGuthabenActivity"
            android:label="@string/addGuthabenTitle"
            android:theme="@style/Theme.AppCompat.Light.Dialog.Alert" />
    </application>

</manifest>

【问题讨论】:

  • 只需删除getApplicationContext()
  • @Mehmet 我删除了 getApplicationContext() 但我得到了同样的错误:java.lang.ClassCastException: android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity at FragmentManager fm = ((AppCompatActivity) 上下文).getSupportFragmentManager();
  • 酒指的是什么?
  • @MehmetKologlu 我不明白你的意思...
  • 错误旁边的行号,是指代码中的哪一行?

标签: android android-fragments android-alertdialog dialogfragment getview


【解决方案1】:

您正在传递一个应用程序上下文,并试图将其转换回 FragmentActivity,这是错误的。您也可以直接传递 Activity 引用。

改变

context = getActivity().getApplicationContext();

context = getActivity();

【讨论】:

  • 不,我不能,什么时候做 Context context = getActivity();我收到一个错误:无法解析 Methode 'getActivity()'
  • okok :) 我删除了 getApplicationContext() 但我得到了同样的错误:java.lang.ClassCastException: android.app.Application 无法在 FragmentManager fm 中转换为 android.support.v7.app.AppCompatActivity = ((AppCompatActivity) 上下文).getSupportFragmentManager();
【解决方案2】:

在适配器的构造函数中,有一个context 参数。将其声明为 fieldthis.context = context;。然后在适配器中需要上下文时使用此上下文。

【讨论】:

  • 我这样做了:public class UserAdapter extends ArrayAdapter&lt;UserCard&gt; { Context mContext; public UserAdapter(Context context, ArrayList&lt;UserCard&gt; userCards) { super(context, 0, userCards); this.mContext = context; } 但我得到了同样的错误:java.lang.ClassCastException: android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity
  • 您是否更改了其余代码? " 然后在适配器中需要上下文时使用此上下文。"我也暗示你不应该施放任何东西
  • 是的,我在需要上下文的地方使用 mContext... 好的,当单击 UserAdapter 中的 holder.plusButton.setOnClickListener() 时,您是否有其他方式或代码来运行 AddBalanceDialog(dialogFragment)?
  • 您是否摆脱了这里的演员表:((AppCompatActivity) context)。这导致了你的问题。您正在尝试将Application 转换为AppCompatActivity,它不是一个
【解决方案3】:

好的,我终于解决了!!!对于对答案感兴趣的人,我是如何做到的:

在我实例化 ArrayAdapter 的 MainActivity.class 中,我将 Context 从 getApplicationContext 更改为 this,如下所示

UserAdapter userAdapter = new UserAdapter(this, arrayOfUsersNames, fm);

我像这样在我的 UserAdapter 的构造函数中添加了 FragmentManager

public class UserAdapter extends ArrayAdapter<UserCard>{
    Context mContext;
    AddBalanceDialog addBalanceDialog = new AddBalanceDialog();
    FragmentManager mFragmentManager;

    public UserAdapter(Context context, ArrayList<UserCard> userCards, FragmentManager fragmentManager) {

        super(context, 0, userCards);
        mContext = context;
        mFragmentManager = fragmentManager;
    }

然后在单击按钮的 onClick() 中,我添加了这行代码,以显示警报对话框 'addBalanceDialog.show(mFragmentManager, "test");' 它奏效了:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多