Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to disable access to fragment's layout(views) from parent activity?

I'm working on a library which will provide fragment with some input fields in it. These input fields will contain user's private information that app which uses my library should not have access to. Therefore edittexts or we can say fragment's layout cannot be accessed from activity(findViewById,getChildAt..) where this fragment is attached to.

Usage of dialog, or another activity is not acceptable, this fragment should be included directly in activity's layout.

Is this even possible in Android ?

I was thinking of creating views dynamically, and overriding methods such as getChildAt to prevent access to child views, but before I start "playing" with this problem, I'd rather ask here for some opinions.

like image 862
Palejandro Avatar asked Apr 12 '16 15:04

Palejandro


3 Answers

Android does not provide a model for such a usage. Overriding methods will certainly make it harder to access these views, but not impossible. Your custom view class has to store its children somewhere. Even if that is a private field, reflection can access it.

An activity has full control over his content, and I don't think you can prevent that.

like image 199
F43nd1r Avatar answered Sep 29 '22 12:09

F43nd1r


First of all what you want is not a good approach, and what i am suggesting is just an idea, its not tested and recommended but can do your work

Create class BaseFragment and extend you each class with Base Fragment must override its getView()

In these approached you have to remove root view as a class member getView returns the same

public class BaseFragment extends Fragment {

    @Nullable
    @Override
    public View getView() {
     super.getView();
    }
}

Now you can do it in two ways

Create boolean in BaseFragment with private access boolean canAccess = true; with no getter and setter and change definition of your getView() to

public BaseFragment() {
    canAccess = false;
}

@Nullable
@Override
public View getView() {
    if(canAccess)
        return super.getView();
    return 
        null;
}

You must call super() for your every child constructors, now if you access getView inside the class canAccess is true so you will get actual view otherwise you will get null.

As per documentation

Get the root view for the fragment's layout (the one returned by {@link #onCreateView}),

if provided @return The fragment's root view, or null if it has no layout.

Second option is much simplest

@Nullable
@Override
public View getView() {
    try {
        throw new Exception("Who called me?");
    } catch (Exception e) {
        String className = e.getStackTrace()[1].getClass().getCanonicalName();
        if (className.equals(YourParentActivity.class.getCanonicalName()))
            return null;
        else
            return super.getView();
    }
}
like image 45
Haris Qurashi Avatar answered Sep 29 '22 10:09

Haris Qurashi


You can disable contents inside your fragment using following method:

public void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) {
    int childCount = viewGroup.getChildCount();
    for(int i = 0; i < childCount; i++) {
        View view = viewGroup.getChildAt(i);
        view.setEnabled(enabled);
        if (view instanceof ViewGroup) {
            enableDisableViewGroup((ViewGroup) view, enabled);
        }
    }
}

You can simply call above method as follows:

enableDisableViewGroup((ViewGroup) rootView, true); // disable

enableDisableViewGroup((ViewGroup) rootView, false); // enable

This method will work for both fragments and adapters to disable/enable their contents.

like image 36
zeeali Avatar answered Sep 29 '22 11:09

zeeali