Запуск DialogFragment в getView пользовательского адаптера
У меня есть обычай 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>
3 ответа
В конструкторе вашего адаптера есть context
параметр. Объявите это как field
с this.context = context;
, Затем используйте этот контекст всякий раз, когда вам нужен контекст в вашем адаптере.
Хорошо, наконец, я решил это!!! для людей, которые заинтересованы в ответе, вот как я это сделал:
в MainActivity.class, где я создаю экземпляр ArrayAdapter, я изменил контекст с getApplicationContext
в this
как это
UserAdapter userAdapter = new UserAdapter(this, arrayOfUsersNames, fm);
и я добавил FragmentManager в конструктор моего UserAdapter, как это
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");
'и это сработало:)
Вы передаете контекст приложения и пытаетесь привести его обратно к FragmentActivity
что неправильно. Вы также можете напрямую передать ссылку на активность.
+ Изменить
context = getActivity().getApplicationContext();
в
context = getActivity();