I'm using SectionedRecyclerViewAdapter to create multiple sections in the recyclerview. The issue is when i trigger switchcompat i want both sections to get updated. It means whenever i change switchcompat state to checked i want the item to get removed from all apps list and get added to locked apps list and vice versa. In other words i want my fragment to get updated whenever i trigger switchcompat.
What is the best way to achieve it?
public class AppListFragment extends Fragment {
Context mContext;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager recyclerViewLayoutManager;
private SectionedRecyclerViewAdapter sectionAdapter;
public AppListFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View appListView = inflater.inflate(R.layout.fragment_app_list,container,false);
sectionAdapter = new SectionedRecyclerViewAdapter();
List<AppItem> lockedAppItemList = getLockedAppList(inflater.getContext());
List<AppItem> allAppItemList = getAllAppList(inflater.getContext());
sectionAdapter.addSection(new SectionLockedApps("Locked Apps", inflater.getContext(),new AppManager(inflater.getContext()).getAllInstalledApkInfo(), lockedAppItemList,sectionAdapter));
sectionAdapter.addSection(new SectionAllApps("All Apps", inflater.getContext(),new AppManager(inflater.getContext()).getAllInstalledApkInfo(), allAppItemList,sectionAdapter));
try {
recyclerView = (RecyclerView) appListView.findViewById(R.id.rv_applist);
recyclerViewLayoutManager = new LinearLayoutManager(this.getContext());
recyclerView.setLayoutManager(recyclerViewLayoutManager);
//adapter = new AppsAdapter(inflater.getContext(), new AppManager(inflater.getContext()).getAllInstalledApkInfo());
recyclerView.setAdapter(sectionAdapter);
}catch (Exception ex){
Log.i("exception",ex.getMessage());
}
return appListView;
}
@Override
public void onResume() {
super.onResume();
if (getActivity() instanceof AppCompatActivity) {
AppCompatActivity activity = ((AppCompatActivity) getActivity());
if (activity.getSupportActionBar() != null) {
activity.getSupportActionBar().setTitle(R.string.app_name);
}
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
private List<AppItem> getLockedAppList(Context ctx) {
AppManager appManager = new AppManager(ctx);
List<AppItem> appItemList = new ArrayList<>();
List<String> apkPackInfoList = appManager.getAllInstalledApkInfo();
for(String apkPackInfo:apkPackInfoList){
String appName = appManager.getAppName(apkPackInfo);
Drawable imageDrawable = appManager.getAppIconByPackageName(apkPackInfo);
Boolean isLocked = appManager.isGuardEnabled(apkPackInfo);
if(isLocked){
appItemList.add(new AppItem(imageDrawable,appName,apkPackInfo,isLocked));
}
}
return appItemList;
}
private List<AppItem> getAllAppList(Context ctx) {
AppManager appManager = new AppManager(ctx);
List<AppItem> appItemList = new ArrayList<>();
List<String> apkPackInfoList = appManager.getAllInstalledApkInfo();
for(String apkPackInfo:apkPackInfoList){
String appName = appManager.getAppName(apkPackInfo);
Drawable imageDrawable = appManager.getAppIconByPackageName(apkPackInfo);
Boolean isLocked = appManager.isGuardEnabled(apkPackInfo);
if(!isLocked){
appItemList.add(new AppItem(imageDrawable,appName,apkPackInfo,isLocked));
}
}
return appItemList;
}
}
public class SectionLockedApps extends StatelessSection {
private SectionedRecyclerViewAdapter sectionAdapter;
String title;
boolean isGuardEnabled;
Context ctxAppList;
List<String> stringList;
List<AppItem> appItemList;
public SectionLockedApps(String title, Context ctx, List<String> stringList, List<AppItem> appItemList, SectionedRecyclerViewAdapter sectionAdapter) {
super(SectionParameters.builder()
.itemResourceId(R.layout.cardview_layout_applist)
.headerResourceId(R.layout.section_header)
.build());
this.title = title;
this.ctxAppList = ctx;
this.stringList = stringList;
this.appItemList = appItemList;
this.sectionAdapter = sectionAdapter;
}
@Override
public int getContentItemsTotal() {
return appItemList.size();
}
@Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
return new ItemViewHolder(view);
}
@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, final int position) {
final AppManager appManager = new AppManager(ctxAppList);
final String applicationPackageName = appItemList.get(position).getPackageName();
isGuardEnabled = appManager.isGuardEnabled(applicationPackageName);
if (appItemList.size() > 0) {
String ApplicationLabelName = appItemList.get(position).getAppName();
Drawable drawable = appItemList.get(position).getImageDrawable();
final ItemViewHolder itemHolder = (ItemViewHolder) holder;
itemHolder.textView_App_Name.setText(ApplicationLabelName);
//viewHolder.textView_App_Package_Name.setText(applicationPackageName);
itemHolder.imageView.setImageDrawable(drawable);
itemHolder.switchCompat.setChecked(isGuardEnabled);
//Adding click listener on CardView to open clicked application directly from here .
itemHolder.rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = ctxAppList.getPackageManager().getLaunchIntentForPackage(applicationPackageName);
if (intent != null) {
ctxAppList.startActivity(intent);
} else {
Toast.makeText(ctxAppList, applicationPackageName + " Error, Please Try Again.", Toast.LENGTH_LONG).show();
}
}
});
itemHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
appManager.setGuard(applicationPackageName, isChecked);
//appItemList.get(position).setLocked(isChecked);
}
});
}
}
@Override
public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
return new HeaderViewHolder(view);
}
@Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
if(appItemList.size()>0){
headerHolder.tvTitle.setText(title);
}else {
headerHolder.tvTitle.setVisibility(View.GONE);
}
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
private final TextView tvTitle;
HeaderViewHolder(View view) {
super(view);
tvTitle = (TextView) view.findViewById(R.id.tvTitle);
}
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
private final View rootView;
public TextView textView_App_Name;
public ImageView imageView;
public SwitchCompat switchCompat;
ItemViewHolder(View view) {
super(view);
rootView = view;
textView_App_Name = (TextView) view.findViewById(R.id.Apk_Name);
imageView = (ImageView) view.findViewById(R.id.imgApplist);
switchCompat = (SwitchCompat) view.findViewById(R.id.compatSwitch);
}
}
}
public class SectionAllApps extends StatelessSection {
String title;
boolean isGuardEnabled;
Context ctxAppList;
List<String> stringList;
List<AppItem> appItemList;
String applicationPackageName;
AppManager appManager;
private SectionedRecyclerViewAdapter sectionAdapter;
public SectionAllApps(String title, Context ctx, List<String> stringList, List<AppItem> appItemList, SectionedRecyclerViewAdapter sectionAdapter) {
super(SectionParameters.builder()
.itemResourceId(R.layout.cardview_layout_applist)
.headerResourceId(R.layout.section_header)
.build());
this.title = title;
this.ctxAppList = ctx;
this.stringList = stringList;
this.appItemList = appItemList;
this.sectionAdapter = sectionAdapter;
}
@Override
public int getContentItemsTotal() {
return appItemList.size();
}
@Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
return new ItemViewHolder(view);
}
@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, final int position) {
final AppManager appManager = new AppManager(ctxAppList);
final String applicationPackageName = appItemList.get(position).getPackageName();
isGuardEnabled = appManager.isGuardEnabled(applicationPackageName);
if (appItemList.size() > 0) {
String ApplicationLabelName = appItemList.get(position).getAppName();
Drawable drawable = appItemList.get(position).getImageDrawable();
final SectionAllApps.ItemViewHolder itemHolder = (SectionAllApps.ItemViewHolder) holder;
itemHolder.textView_App_Name.setText(ApplicationLabelName);
//viewHolder.textView_App_Package_Name.setText(applicationPackageName);
itemHolder.imageView.setImageDrawable(drawable);
itemHolder.switchCompat.setChecked(isGuardEnabled);
//Adding click listener on CardView to open clicked application directly from here .
itemHolder.rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = ctxAppList.getPackageManager().getLaunchIntentForPackage(applicationPackageName);
if (intent != null) {
ctxAppList.startActivity(intent);
} else {
Toast.makeText(ctxAppList, applicationPackageName + " Error, Please Try Again.", Toast.LENGTH_LONG).show();
}
}
});
itemHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
appManager.setGuard(applicationPackageName, isChecked);
//appItemList.get(position).setLocked(isChecked);
}
});
}
}
@Override
public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
return new HeaderViewHolder(view);
}
@Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
headerHolder.tvTitle.setText(title);
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
private final TextView tvTitle;
HeaderViewHolder(View view) {
super(view);
tvTitle = (TextView) view.findViewById(R.id.tvTitle);
}
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
private final View rootView;
public ImageView imageView;
public TextView textView_App_Name;
public SwitchCompat switchCompat;
ItemViewHolder(View view) {
super(view);
rootView = view;
imageView = (ImageView) view.findViewById(R.id.imgApplist);
textView_App_Name = (TextView) view.findViewById(R.id.Apk_Name);
switchCompat = (SwitchCompat) view.findViewById(R.id.compatSwitch);
}
}
}
appManager.SetGuard() basically saves switchcompat's last state.
After some research I've found a solution for my issue. The solution was not to work with list of apps but to refresh the fragment. Basically I've created an interface that is used for both of my sections on scenario execute with method refresh();
and made an implementation inside my fragment
Codes are written below:
public interface IFragmentOperation {
public void refresh();
}
public class AppListFragment extends Fragment implements IFragmentOperation {
....
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
sectionAdapter.addSection(new SectionLockedApps("Locked Apps", inflater.getContext(),lockedAppItemList,this));
sectionAdapter.addSection(new SectionAllApps("All Apps", inflater.getContext(),allAppItemList,this));
...
}
//Refresh fragment on switchcompat touched
@Override
public void refresh() {
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.detach(this).attach(this).commit();
}
}
As you can see I've implemented an interface with method refresh()
and added an extra parameter this inside my sections cunstructor. This way I'm sending an interface implementation into my section classes.
Then in my section I simply create IFragmentOperation fragmentOperation;
and assigning the value of fragmentOperation
inside constructor
IFragmentOperation fragmentOperation;
public SectionLockedApps(String title, Context ctx,List<AppItem> appItemList,IFragmentOperation fragmentOperation) {
super(SectionParameters.builder()
.itemResourceId(R.layout.cardview_layout_applist)
.headerResourceId(R.layout.section_header)
.build());
this.title = title;
this.ctxAppList = ctx;
this.appItemList = appItemList;
this.fragmentOperation = fragmentOperation;
}
and use it wherever is needed like this fragmentOperation.refresh();
itemHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
appManager.setGuard(applicationPackageName, isChecked);
//appItemList.get(position).setLocked(isChecked);
fragmentOperation.refresh();
}
});
That's it. Hope it will help someone with related issue.