回收者视图中的每个钱包都有一个设置活动,我可以使用以下代码从其设置活动中删除回收器项目
执行删除功能后,我试图使回收者视图更新,但我的钱包片段中不断出现空指针异常
Settings.kt
class WalletSettings : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.settings_activity)
supportFragmentManager
.beginTransaction()
.replace(R.id.settings, SettingsFragment())
.commit()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val txtName = findViewById<View>(R.id.title) as TextView
txtName.text = "Settings"
val subTitle = findViewById<View>(R.id.sub_title) as TextView
subTitle.visibility = View.VISIBLE
subTitle.text = intent.extras!!.getString("walletname")
val leftImageView = findViewById<View>(R.id.go_back) as ImageView
leftImageView.setImageResource(R.drawable.ic_action_navigation_arrow_back)
leftImageView.setColorFilter(ContextCompat.getColor(applicationContext, R.color.colorPrimary))
leftImageView.setOnClickListener { finish() }
val rightImageView = findViewById<View>(R.id.notification) as ImageView
rightImageView.visibility = View.INVISIBLE
}
class SettingsFragment : PreferenceFragmentCompat() {
var walletsFragment: WalletsFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
walletsFragment = WalletsFragment()
Log.i(TAG, "----------oncreate fragment $walletsFragment")
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
val deleteWallet: Preference? = findPreference(getString(R.string.delete))
deleteWallet!!.setOnPreferenceClickListener { //code for what you want it to do
Toast.makeText(context, "Delete wallet clicked", Toast.LENGTH_SHORT).show();
deleteWalletUser();
true
}
val changePIN: Preference? = findPreference(getString(R.string.change_pin))
changePIN!!.setOnPreferenceClickListener { //code for what you want it to do
Toast.makeText(context, "Change PIN clicked", Toast.LENGTH_SHORT).show();
true
}
val useFingerprint: Preference? = findPreference(getString(R.string.fingerprint))
useFingerprint!!.setOnPreferenceClickListener { //code for what you want it to do
Toast.makeText(context, "Use fingerprint clicked", Toast.LENGTH_SHORT).show();
false
}
}
private fun deleteWalletUser() {
val walletID = requireActivity().intent.extras!!.getInt("walletid")
val stringRequest: StringRequest = object : StringRequest(Method.DELETE, URLs.URL_USER_DELETE_WALLET + walletID,
Response.Listener { response ->
// progressBar.setVisibility(View.GONE);
try {
//converting response to json object
val obj = JSONObject(response)
//if no error in response
if (obj.getBoolean("success")) {
Toast.makeText(context, obj.getString("message"), Toast.LENGTH_SHORT).show()
requireActivity().finish()
Log.i(TAG, "----------ondelete $walletsFragment")
walletsFragment!!.updateWalletFragment()
} else {
Toast.makeText(context, obj.getString("message"), Toast.LENGTH_SHORT).show()
}
} catch (e: JSONException) {
e.printStackTrace()
}
},
Response.ErrorListener { error -> Toast.makeText(context, error.message, Toast.LENGTH_SHORT).show() }) {
@Throws(AuthFailureError::class)
override fun getParams(): Map<String, String> {
val params: MutableMap<String, String> = HashMap()
// params["wallet_name"] = walletID
return params
}
}
VolleySingleton.getInstance(context).addToRequestQueue(stringRequest)
}
}
}
WalletFragment.java
public class WalletsFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private static String TAG = HomeFragment.class.getSimpleName();
private TextView name;
private TextView score;
private SwipeRefreshLayout swipeRefreshLayout;
private ArrayList<Wallet> userWalletList;
private ProgressDialog progressDialog;
boolean mIsRequest = false;
private WalletsViewModel walletsViewModel;
private ShimmerFrameLayout mShimmerViewContainer;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
walletsViewModel =
ViewModelProviders.of(this).get(WalletsViewModel.class);
View root = inflater.inflate(R.layout.fragment_wallets, container, false);
TextView txtName = (TextView) root.findViewById(R.id.title);
txtName.setText("Wallets");
ImageView rightImageView = (ImageView) root.findViewById(R.id.notification);
rightImageView.setImageResource(R.drawable.ic_action_account_balance_wallet);
rightImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.colorPrimary));
rightImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CreateWalletDialog createWalletFragment = new CreateWalletDialog();
createWalletFragment.show(getChildFragmentManager(), createWalletFragment.getTag());
// CustomAlertDialog cdd=new CustomAlertDialog(getActivity());
// cdd.show();
// Toast.makeText(getContext(),"Create a new wallet", Toast.LENGTH_SHORT).show();
}
});
mShimmerViewContainer = root.findViewById(R.id.shimmer_view_container);
mRecyclerView = (RecyclerView) root.findViewById(R.id.recycler_view);
swipeRefreshLayout = (SwipeRefreshLayout) root.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setColorSchemeColors(getResources().getColor(android.R.color.holo_green_dark),
getResources().getColor(android.R.color.holo_red_dark),
getResources().getColor(android.R.color.holo_blue_dark),
getResources().getColor(android.R.color.holo_orange_dark));
mRecyclerView.setHasFixedSize(true);
SnapHelper helper = new LinearSnapHelper();
helper.attachToRecyclerView(mRecyclerView);
mLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
//initializing the walletlist
userWalletList = new ArrayList<>();
loadUserWallets();
return root;
}
private void loadUserWallets() {
// swipeRefreshLayout.setRefreshing(true);
// progressDialog = ProgressDialog.show(getActivity(), "Fetching All Time Earners","Please Wait....", true);
/*
* Creating a String Request
* The request type is GET defined by first parameter
* The URL is defined in the second parameter
* Then we have a Response Listener and a Error Listener
* In response listener we will get the JSON response as a String
* */
if(mIsRequest)
return;
mIsRequest= true;
userWalletList.clear();
User user = SharedPrefManager.getInstance(getContext()).getUser();
StringRequest stringRequest = new StringRequest(Request.Method.GET, URLs.URL_USER_WALLET_LIST + user.getId(),
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mIsRequest = false;
try {
//converting the string to json object
JSONObject object=new JSONObject(response);
//getting data array from json response object
JSONArray array=object.getJSONArray("data");
for(int i=0;i<array.length();i++) {
//getting wallet object from json array
JSONObject userWallets=array.getJSONObject(i);
//adding the wallet to wallet list
userWalletList.add(new Wallet(
userWallets.getInt("id"),
userWallets.getInt("user_id"),
userWallets.getString("wallet_name"),
userWallets.getInt("wallet_id"),
userWallets.getInt("wallet_type"),
userWallets.getDouble("balance")
));
}
//creating adapter object and setting it to recyclerview
WalletAdapter adapter = new WalletAdapter(getActivity(),getChildFragmentManager(), userWalletList);
mRecyclerView.setAdapter(adapter);
swipeRefreshLayout.setRefreshing(false);
// stop animating Shimmer and hide the layout
mShimmerViewContainer.stopShimmerAnimation();
mShimmerViewContainer.setVisibility(View.GONE);
// progressDialog.dismiss();
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mIsRequest = false;
// progressDialog.dismiss();
// swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getContext(),"No Internet Connection", Toast.LENGTH_SHORT).show();
}
});
//adding our stringrequest to queue
Volley.newRequestQueue(getContext()).add(stringRequest);
}
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
User user = SharedPrefManager.getInstance(getContext()).getUser();
VolleySingleton.getInstance(getContext()).getRequestQueue().getCache().invalidate(URLs.URL_USER_WALLET_LIST + user.getId(), true);
loadUserWallets();
}
public void updateWalletFragment(){
loadUserWallets();
}
@Override
public void onResume() {
super.onResume();
mShimmerViewContainer.startShimmerAnimation();
}
@Override
public void onPause() {
mShimmerViewContainer.stopShimmerAnimation();
super.onPause();
}
}
我得到java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.ArrayList.clear()' on a null object reference
at com.dreacot.dreacotwallet.ui.wallets.WalletsFragment.loadUserWallets(WalletsFragment.java:123)' on a null object reference
如果我删除了导致空指针的代码,则会得到其他空指针
我认为问题是我正在创建一个新的钱包碎片实例,而不是重用旧实例,如果是这样,我该如何重用旧实例
可能还需要注意,这就是我从钱包适配器打开活动的方式
WalletAdapter.java
private void showSettingsActivity(RecyclerView.ViewHolder dataObjectHolder){
Intent intent = new Intent(mCtx , WalletSettings.class);
Bundle bundle = new Bundle();
String walletName = userWalletList.get(dataObjectHolder.getAdapterPosition()).getWalletName();
int walletID = userWalletList.get(dataObjectHolder.getAdapterPosition()).getId();
bundle.putString("walletname", walletName);
bundle.putInt("walletid", walletID);
intent.putExtras(bundle);
mCtx.startActivity(intent);
}
还有片段的代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navView = findViewById(R.id.nav_view);
addBadgeView();
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home, R.id.navigation_transactions, R.id.navigation_wallets, R.id.navigation_account)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
// NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
}
答案 0 :(得分:1)
当您进入另一个WalletFragment
时,您将无法获得Activity
。对于您的情况,简单的解决方案是您应该使用方法startActivityForResult
。
WalletAdapter
中传递walletFragment
,更改其构造函数。private Fragment mFragment;
WalletAdapter(FragmentManager manager, ArrayList<Wallet> list, Fragment fragment) {
// your init
mFragment = fragment;
}
private void showSettingsActivity(RecyclerView.ViewHolder dataObjectHolder){
Intent intent = new Intent(mCtx , WalletSettings.class);
Bundle bundle = new Bundle();
String walletName = userWalletList.get(dataObjectHolder.getAdapterPosition()).getWalletName();
int walletID = userWalletList.get(dataObjectHolder.getAdapterPosition()).getId();
bundle.putString("walletname", walletName);
bundle.putInt("walletid", walletID);
intent.putExtras(bundle);
mFragment.startActivityForResult(intent, 123); // you can define request code
}
WalletFragment
中覆盖onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == 123) {
updateWalletFragment();
}
}
SettingsFragment
中,删除与walletFragment
相关的所有代码,然后更改为此内容if (obj.getBoolean("success")) {
Toast.makeText(context, obj.getString("message"), Toast.LENGTH_SHORT).show()
requireActivity().setResult(Activity.RESULT_OK)
requireActivity().finish()
}