问题
I am having this following error. I added constructor on DailyVerseFragment. But still it doesn't work. I am having this issues for more than one week.
Fatal Exception: java.lang.RuntimeException
Unable to start activity ComponentInfo{com.donghyouny.biblecard/com.donghyouny.biblecard.MainActivity}: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.donghyouny.biblecard.DailyVerseFragment: could not find Fragment constructor
package com.donghyouny.biblecard;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.Menu;
import android.view.ViewGroup;
import android.widget.Button;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.core.view.GravityCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, FragmentCallback {
Toolbar toolbar;
CardFragment cardFargment;
DailyVerseFragment dailyVerseFragment;
private AppBarConfiguration mAppBarConfiguration;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dailyVerseFragment = new DailyVerseFragment();
// mAuth = FirebaseAuth.getInstance();
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
contextOfApplication = getApplicationContext();
toolbar.setTitle("Draw Verse Card");
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
drawer.openDrawer(GravityCompat.START);
cardFargment = new CardFragment();
Calendar mCalendar = Calendar.getInstance();
/*mCalendar.set(Calendar.HOUR_OF_DAY, 01);
mCalendar.set(Calendar.MINUTE, 01);
mCalendar.set(Calendar.SECOND, 0);*/
mCalendar.set(Calendar.HOUR_OF_DAY, 0);
if(mCalendar.before(Calendar.getInstance())){ // if it's in the past, increment
mCalendar.add(Calendar.DATE, 1);
}
// PackageManager pm = this.getPackageManager();
// ComponentName receiver = new ComponentName(this, DeviceBootReceiver.class);
Intent alarmIntent = new Intent(this, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), pendingIntent);
}
}
// 부팅 후 실행되는 리시버 사용가능하게 설정
/* pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);*/
// setAlarm(mCalendar);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
getSupportFragmentManager().beginTransaction().add(R.id.container, cardFargment).commit();
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else{
// super.onBackPressed();
AlertDialog.Builder alBuilder = new AlertDialog.Builder(this, R.style.AlertDialogCustom);
alBuilder.setMessage("Do you want to exit?");
// "예" 버튼을 누르면 실행되는 리스너
alBuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish(); // 현재 액티비티를 종료한다. (MainActivity에서 작동하기 때문에 애플리케이션을 종료한다.)
}
});
// "아니오" 버튼을 누르면 실행되는 리스너
alBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
return; // 아무런 작업도 하지 않고 돌아간다
}
});
alBuilder.setTitle("Program Exit");
alBuilder.show(); // AlertDialog.Bulider로 만든 AlertDialog를 보여준다.
}
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Bundle bundle = getBundle(menuItem);
// onFragmentSelected(0, bundle);
int id = menuItem.getItemId();
if(id == R.id.menu1){
onFragmentSelected(0, bundle);
}else if(id == R.id.menu2){
onFragmentSelected(1, bundle);
}else if(id == R.id.menu3) {
onFragmentSelected(2, bundle);
}else if(id == R.id.menu4) {
onFragmentSelected(3, bundle);
}else if(id == R.id.menu5) {
onFragmentSelected(4, bundle);
}else if(id == R.id.menu6) {
onFragmentSelected(5, bundle);
}else if(id == R.id.menu7) {
onFragmentSelected(6, bundle);
}else if(id == R.id.menu8) {
onFragmentSelected(7, bundle);
}else if(id == R.id.menu9) {
onFragmentSelected(8, bundle);
}else if(id == R.id.menu10) {
onFragmentSelected(9, bundle);
}else if(id == R.id.menu11) {
onFragmentSelected(10, bundle);
}else if(id == R.id.menu12) {
onFragmentSelected(11, bundle);
}else if(id == R.id.menu13) {
onFragmentSelected(12, bundle);
}else if(id == R.id.menu14) {
onFragmentSelected(13, bundle);
}else if(id == R.id.menu15) {
onFragmentSelected(14, bundle);
}else if(id == R.id.menu16) {
onFragmentSelected(15, bundle);
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private Bundle getBundle(@NonNull MenuItem menuItem) {
Bundle bundle = new Bundle();
bundle.putString("value", menuItem.getTitle().toString());
return bundle;
}
@Override
public void onFragmentSelected(int position, Bundle bundle) {
String value = bundle.getString("value");
Fragment curFragment = null;
if(position == 0){
curFragment = new CardFragment();
toolbar.setTitle(value);
}else if(position==1){
curFragment = new DailyVerseFragment(toolbar);
//toolbar.setTitle(value);
}else if(position>=2){
curFragment = new Fragment1(value);
toolbar.setTitle(value);
}
// toolbar.setTitle(value);
getSupportFragmentManager().beginTransaction().replace(R.id.container, curFragment).commit();
}
// a static variable to get a reference of our application context
public static Context contextOfApplication;
public static Context getContextOfApplication()
{
return contextOfApplication;
}
}
package com.donghyouny.biblecard;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.google.android.gms.ads.AdView;
public class DailyVerseFragment extends Fragment {
private ImageView imageView;
private TextView bibleType;
private TextView verse;
private TextView content;
public Bible bible;
private SharedPreferences checkDialog;
private SharedPreferences saveDialog;
private SharedPreferences shareDialog;
private ImageView like;
private ImageView check;
private ImageView save;
private TextView likecount, savecount, link;
public static final int REQUEST_CODE = 101;
private String key;
private Toolbar toolbar;
private boolean flag;
private AdView mAdView;
private String categoryName;
private DrawableImage DrawbleImage;
private AlertReceiver AlertReceivr;
public DailyVerseFragment(){}
public DailyVerseFragment(Toolbar value) {
this.toolbar = value;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
Activity a = getActivity();
if (a != null) a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_daily_verse, container, false);
// toolbar = rootView.findViewById(R.id.toolbar);
// ((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
verse = rootView.findViewById(R.id.verse);
content = rootView.findViewById(R.id.content);
imageView = rootView.findViewById(R.id.imageView);
save = rootView.findViewById(R.id.save);
SharedPreferences sharedPreferences = getActivity().getSharedPreferences("bibleNum", Context.MODE_PRIVATE);
final int bibleNum = sharedPreferences.getInt("bibleNum", 1);
Log.d("DailyVerseNum", String.valueOf(bibleNum));
MyDatabaseHelper db = new MyDatabaseHelper(getActivity());
Cursor cursor = db.readDailyCardData(bibleNum);
cursor.moveToFirst();
bible = new Bible();
Log.d("cursorid", String.valueOf(cursor.getInt(0)));
bible.setId(cursor.getInt(0));
bible.setVerse(cursor.getString(1));
bible.setContent(cursor.getString(2));
bible.setNum(cursor.getInt(3));
bible.setCnum(cursor.getInt(4));
bible.setVnum(cursor.getInt(5));
bible.setImage(cursor.getBlob(6));
bible.setTimestamp(cursor.getString(7));
Log.d("content", bible.getContent());
Log.d("bible.getCnum", String.valueOf(bible.getCnum()));
Cursor cursor1 = db.getCategoryName(bible.getCnum());
cursor1.moveToFirst();
categoryName = cursor1.getString(0);
display();
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
saveDialog = getActivity().getSharedPreferences("saveDialog", Context.MODE_PRIVATE);
boolean isFirst = saveDialog.getBoolean("first", true);
if(isFirst){
saveDialogPopup();
}else{
onSave(bible);
}
}
});
setHasOptionsMenu(true);
return rootView;
}
private void checkMethod(Bible bible) {
MyDatabaseHelper db = new MyDatabaseHelper(getContext());
db.updateData(bible);
}
private void checkDialogPopup() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.AlertDialogCustom);
builder.setTitle("Check Button");
builder.setMessage("If you want to specify which verse is already read, this button will move the one you read to the lowest of the previously show list. But once you click this button, you cannot revert it. Do you want to proceed?");
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(),"You select 'Yes'.",Toast.LENGTH_SHORT).show();
checkMethod(bible);
}
});
builder.setNegativeButton("Don't show this message, again.",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SharedPreferences.Editor editor = checkDialog.edit();
editor.putBoolean("firstTime", false);
editor.commit();
Toast.makeText(getContext(),"You select 'Don't show this message, again.'",Toast.LENGTH_SHORT).show();
}
});
builder.show();
}
private void onSave(Bible bible) {
Log.d("getId", String.valueOf(bible.getId()));
MyDatabaseHelper db1 = new MyDatabaseHelper(getContext());
Cursor cursor = db1.getSaveDataById(bible.getId());
flag=true;
cursor.moveToFirst();
Log.d("countcursor", String.valueOf(cursor.getCount()));
if (cursor != null && cursor.moveToFirst()) {
Toast.makeText(getContext(),"It is already saved.",Toast.LENGTH_SHORT).show();
flag = false;
}else if(flag){
db1.insertToSave(bible);
cursor.close();
}
}
private void saveDialogPopup() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.AlertDialogCustom);
builder.setTitle("Save Button");
builder.setMessage("If you select this button, the verse you read will be saved and if you want to see that verse that you saved, you should go to verse list and on the top right, you will see yellow folder icon. If you click that icon. It will take you to 'favorite bible verse'. If you want to save?");
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
onSave(bible);
}
});
builder.setNegativeButton("Don't show this message, again.",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SharedPreferences.Editor editor = saveDialog.edit();
editor.putBoolean("first", false);
editor.commit();
Toast.makeText(getContext(),"You select not \'Don\'t show this message, again\'.",Toast.LENGTH_SHORT).show();
}
});
builder.show();
}
double getScreenInches() {
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
double wi = (double) width / (double) dm.xdpi;
double hi = (double) height / (double) dm.ydpi;
double x = Math.pow(wi, 2);
double y = Math.pow(hi, 2);
double screenInches = Math.sqrt(x + y);
return screenInches;
}
private void display(){
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
params.width = metrics.widthPixels;
params.height = (int)(metrics.heightPixels/2.8);
Log.d("width", String.valueOf(params.width));
Log.d("height", String.valueOf(params.height));
imageView.setLayoutParams(params);
Glide.with(getContext()).load(bible.getImage()).apply(new RequestOptions().centerCrop()).into(imageView);
//imageView.setImageResource(R.drawable.church);
verse.setText(bible.getVerse().toString());
content.setText(bible.getContent().toString());
Log.d("content", bible.getContent().toString());
int inch = (int)( getScreenInches()+0.5 );
Log.d("inch", String.valueOf(3*inch));
//content.setTextSize(3*inch);
toolbar.setTitle(categoryName);
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.share_actions, menu);
}
public void shareDialogPopup(){
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.AlertDialogCustom);
builder.setTitle("Share Button");
builder.setMessage("You can share bible verse that you read by clicking this button. Do you want to proceed?");
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(),"You select \'Yes\'.",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, bible.getVerse()+"\n"+bible.getContent()+"\n"+"https://play.google.com/store/apps/details?id=the.holy.catholic.bible");
Intent chooser = Intent.createChooser(intent, "Share");
startActivity(chooser);
}
});
builder.setNegativeButton("Don\'t show this message, again",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SharedPreferences.Editor editor = shareDialog.edit();
editor.putBoolean("printMsg", false);
editor.commit();
Toast.makeText(getContext(),"You select not \'Don\'t show this message, again\'.",Toast.LENGTH_SHORT).show();
}
});
/*AlertDialog alert = builder.create();
alert.show();
alert.getWindow().getAttributes();
TextView textView = (TextView) alert.findViewById(android.R.id.message);
textView.setTextSize(15);
Button btn1 = alert.getButton(DialogInterface.BUTTON_NEGATIVE);
Button btn2 = alert.getButton(DialogInterface.BUTTON_POSITIVE);
btn1.setTextSize(12);
btn2.setTextSize(12);*/
builder.show();
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.share:
shareDialog = getActivity().getSharedPreferences("shareDialog", Context.MODE_PRIVATE);
boolean printMsg = shareDialog.getBoolean("printMsg", true);
if(printMsg){
shareDialogPopup();
}else{
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, bible.getVerse()+"\n"+bible.getContent()+"\n"+"https://play.google.com/store/apps/details?id=the.holy.catholic.bible");
Intent chooser = Intent.createChooser(intent, "Share");
startActivity(chooser);
break;
}
}
return super.onOptionsItemSelected(item);
}
}
回答1:
The Problem that caused your crash is that you want to instantiate your fragment with a constructor with parameter. but you in android you should create fragment with a non parameter constructor. so how to solve this problem to pass parameters in to your fragment:
in DailyVerseFragment :
public static DailyVerseFragment newInstance(String myString) {
DailyVerseFragment myFragment = new DailyVerseFragment();
Bundle args = new Bundle();
args.putString("key", myString);
myFragment.setArguments(args);
return myFragment;
}
and in onCreate() function of fragment get it like :
getArguments().getString("key");
and if you want to send Objects you can use putParcable/getParcable.
but my suggestion for you to get toolbar in your fragment is to access it in your fragment like this:
((AppCompatActivity) getActivity()).getSupportActionBar()
来源:https://stackoverflow.com/questions/62930952/unable-to-instantiate-fragment-could-not-find-fragment-constructor-android