因此,我已经花了数小时在这里浏览帖子并尝试各种解决方案,但是我真的不知道为什么每次尝试更改QuotesFragment的背景时应用程序崩溃。基本上,在SettingsFragment中,用户从微调器中选择一个主题,一个内部类获取该值,并使用一个接口将该值传递给QuotesFragment,这将更改其背景。
我本来是想从SettingsFragment中更改它的,但这似乎是一个更大的麻烦。我真的只希望更改特定片段的背景,而不是每个片段。最初,我为QuotesFragment提供了一种相对布局,然后尝试对其进行更改,但是我在网上看到的一个建议是为背景嵌套一个RelativeLayout。
几乎每当我单击SettingsFragment中的“保存”按钮时,应用程序就会崩溃。在尝试实施后台更改之前,一切都在进行,所以我觉得这与之有关。任何帮助将不胜感激。另外,我在此处发布的经验不足,如果这不是应该的样子,请对不起。
public class SettingsFragment extends Fragment implements AdapterView.OnItemSelectedListener {
private Switch notificationSwitch;
private TextView notificationsTV;
private TextView perDayTV;
private Button saveButton;
private Button clearButton;
ArrayList<Calendar> calList;
Spinner quotesSpinner;
Spinner themesSpinner;
private int QUOTES_SPINNER_VALUE;
private String THEMES_SPINNER_VALUE;
public interface BackgroundThemeListener{
void themeSelected(String theme);
}//interface
private BackgroundThemeListener bgListener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.settings_fragment, container, false);
getActivity().setTitle("Settings");
THEMES_SPINNER_VALUE = "";
QUOTES_SPINNER_VALUE = 0;
notificationSwitch = view.findViewById(R.id.notification_switch);
notificationsTV = view.findViewById(R.id.notifications_onoff_textview);
perDayTV = view.findViewById(R.id.per_day_textview);
saveButton = view.findViewById(R.id.save_button);
clearButton = view.findViewById(R.id.clear_button);
calList = new ArrayList<>();
quotesSpinner = view.findViewById(R.id.per_day_spinner);
ArrayAdapter<CharSequence> quotesAdapter = ArrayAdapter.createFromResource(getContext(), R.array.quotes_per_day_numbers, android.R.layout.simple_spinner_item);
quotesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
quotesSpinner.setAdapter(quotesAdapter);
quotesSpinner.setOnItemSelectedListener(this);
themesSpinner = view.findViewById(R.id.themes_spinner);
ArrayAdapter<CharSequence> themeAdapter = ArrayAdapter.createFromResource(getContext(), R.array.bg_themes, android.R.layout.simple_spinner_item);
themeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
themesSpinner.setAdapter(themeAdapter);
themesSpinner.setOnItemSelectedListener(new ThemesSpinnerClass());
notificationSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
perDayTV.setVisibility(View.VISIBLE);
quotesSpinner.setVisibility(View.VISIBLE);
saveButton.setVisibility(View.VISIBLE);
clearButton.setVisibility(View.VISIBLE);
Toast.makeText(getActivity(), "Notifications On", Toast.LENGTH_SHORT);
} else{
perDayTV.setVisibility(View.INVISIBLE);
quotesSpinner.setVisibility(View.INVISIBLE);
saveButton.setVisibility(View.INVISIBLE);
clearButton.setVisibility(View.INVISIBLE);
Toast.makeText(getActivity(), "Notifications Cleared", Toast.LENGTH_SHORT);
}//if/else
}//onCheckChanged
});
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bgListener.themeSelected(THEMES_SPINNER_VALUE);
int hour;
int minute;
//for loop adding calendars to the list
for (int i = 0; i < QUOTES_SPINNER_VALUE; i++){
Calendar cal = Calendar.getInstance();
hour = (int) (Math.random() % 24) + 1;
minute = (int) (Math.random() % 60) + 1;
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, 0);
calList.add(cal);
}//for
Toast.makeText(getActivity(), "Times Set Randomly", Toast.LENGTH_SHORT).show();
startAlarm();
bgListener.themeSelected(THEMES_SPINNER_VALUE);
}//onClick
});
clearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (Calendar cal : calList) {
cancelAlarm();
}//for
Toast.makeText(getActivity(), "Notifications Cleared", Toast.LENGTH_SHORT).show();
}
});
return view;
}//onCreateView method
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
QUOTES_SPINNER_VALUE = Integer.parseInt(quotesSpinner.getSelectedItem().toString());
}//onItemSelected method
@Override
public void onNothingSelected(AdapterView<?> parent) {
}//onNothingSelected method
private void startAlarm(){
for (Calendar cal : calList) {
AlarmManager alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1, intent, 0);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmManager.INTERVAL_DAY, pendingIntent);
}//for
}//startAlarm method
private void cancelAlarm(){
AlarmManager alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1, intent, 0);
alarmManager.cancel(pendingIntent);
}//cancelAlarm method
@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof BackgroundThemeListener){
bgListener = (BackgroundThemeListener) context;
}//if
else{
throw new RuntimeException(context.toString() + " must implement BackgroundThemeListener");
}//else
}//onAttach method
@Override
public void onDetach() {
super.onDetach();
bgListener = null;
}//onDetach method
class ThemesSpinnerClass implements AdapterView.OnItemSelectedListener{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
THEMES_SPINNER_VALUE = themesSpinner.getItemAtPosition(position).toString();
//bgListener.themeSelected(THEMES_SPINNER_VALUE);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}//ThemesSpinnerClass
}//SettingsFragment class
import static com.abc.danielharrington.betterdays.BetterDays.CHANNEL_1_ID;
import static com.abc.danielharrington.betterdays.BetterDays.CHANNEL_2_ID;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, SettingsFragment.BackgroundThemeListener {
private DrawerLayout drawer;
private NotificationManagerCompat notificationManager;
private QuotesFragment quotesFragment;
private AboutFragment aboutFragment;
private SettingsFragment settingsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
quotesFragment = new QuotesFragment();
aboutFragment = new AboutFragment();
settingsFragment = new SettingsFragment();
notificationManager = NotificationManagerCompat.from(this);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
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();
NavigationView navView = findViewById(R.id.nav_view);
navView.setNavigationItemSelectedListener(this);
if(savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new QuotesFragment()).commit();
navView.setCheckedItem(R.id.nav_quotes);
}//if
}//onCreate method
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.nav_quotes:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, quotesFragment).commit();
break;
case R.id.nav_about:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, aboutFragment).commit();
break;
case R.id.nav_settings:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, settingsFragment).commit();
break;
case R.id.nav_share:
break;
}//switch
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
public void onBackPressed(){
if(drawer.isDrawerOpen(GravityCompat.START)){
drawer.closeDrawer(GravityCompat.START);
}else {
super.onBackPressed();
}
}//onBackPressed
public void sendOnChannel1(View view){
String title = "Better Days";
String message = "New Quote Available";
Notification notification = new NotificationCompat.Builder(this, CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_quotes)
.setContentTitle(title).setContentText(message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
notificationManager.notify(1, notification);
}//sendOnChannel1 method
public void sendOnChannel2(View view){
String title = "Better Days";
String message = "New Quote Available";
Notification notification = new NotificationCompat.Builder(this, CHANNEL_2_ID)
.setSmallIcon(R.drawable.ic_quotes)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
notificationManager.notify(2, notification);
}//sendOnChannel2 method
@Override
public void themeSelected(String theme) {
quotesFragment.updateTheme(theme);
}//themeSelected
}//MainActivity class
public class QuotesFragment extends Fragment {
private DrawerLayout drawer;
private RelativeLayout quotesLayout;
private String BG_THEME;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.quotes_fragment, container, false);
getActivity().setTitle("Quotes");
quotesLayout = rootView.findViewById(R.id.quotes_bg_layout);
//quotesLayout.setBackgroundResource(R.drawable.img_forest);
return rootView;
}//onCreateView method
public void updateTheme(String theme){
BG_THEME = theme;
if (theme.equals("Forest")){
quotesLayout.setBackgroundResource(R.drawable.img_forest);
}
//setQuotesBackground();
}//updateTheme method
//method to change the quotes fragment background based on user preference
private void setQuotesBackground(){
if(BG_THEME.equals("Forest")){
quotesLayout.setBackgroundResource(R.drawable.img_forest);
}
/*
switch(BG_THEME){
case "Default":
quotesLayout.setBackgroundColor(getActivity().getResources().getColor(R.color.signBlue));
break;
case "Forest":
quotesLayout.setBackgroundResource(R.drawable.img_forest);
quotesLayout.invalidate();
break;
case "Space":
quotesLayout.setBackground(getActivity().getResources().getDrawable(R.drawable.img_space));
break;
case "Mountain":
quotesLayout.setBackground(getActivity().getResources().getDrawable(R.drawable.img_mountain));
break;
case "Beach":
quotesLayout.setBackground(getActivity().getResources().getDrawable(R.drawable.img_beach));
break;
default:
quotesLayout.setBackgroundColor(getActivity().getResources().getColor(R.color.signBlue));
break;
}//switch
*/
}//setQuotesBackground method
}//QuotesFragment class
这是错误的意思:
E / Android运行时:致命异常:主要 流程:com.abc.danielharrington.betterdays,PID:4744 java.lang.NullPointerException:尝试在虚拟设备上调用虚拟方法'void android.widget.RelativeLayout.setBackgroundResource(int)' 空对象引用 在com.abc.danielharrington.betterdays.QuotesFragment.updateTheme(QuotesFragment.java:45) 在com.abc.danielharrington.betterdays.MainActivity.themeSelected(MainActivity.java:131) 在com.abc.danielharrington.betterdays.SettingsFragment $ 2.onClick(SettingsFragment.java:101) 在android.view.View.performClick(View.java:6597) 在android.view.View.performClickInternal(View.java:6574) 在android.view.View.access $ 3100(View.java:778) 在android.view.View $ PerformClick.run(View.java:25885) 在android.os.Handler.handleCallback(Handler.java:873) 在android.os.Handler.dispatchMessage(Handler.java:99) 在android.os.Looper.loop(Looper.java:193) 在android.app.ActivityThread.main(ActivityThread.java:6669) 在java.lang.reflect.Method.invoke(本机方法) 在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:493) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
答案 0 :(得分:-1)
尝试下面的OnViewCreated方法中的代码。
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
quotesLayout = view.findViewById(R.id.quotes_bg_layout);
quotesLayout.setBackgroundResource(R.drawable.img_forest);
}
如果上面的代码不起作用,这意味着您膨胀了错误的布局或可绘制的img森林与设置为背景(例如png,jpg)不兼容。尝试其他图片。