Handle a View Visibility Change Without Overriding the View

Handle a view visibility change without overriding the view

You can use a GlobalLayoutListener to determine if there are any changes in the views visibility.

myView.setTag(myView.getVisibility());
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int newVis = myView.getVisibility();
if((int)myView.getTag() != newVis)
{
myView.setTag(myView.getVisibility());
//visibility has changed
}
}
});

How to change visibility of a view in custom dialog after showing it android

Use LayoutInflator you might want to override AlertDialog's Button because
it will dismiss() by default onClick()

    View view = getLayoutInflater().inflate(R.layout.your_inflated_layout, null);

final LinearLayout linearLayout = view.findViewById(R.id.your_linear);
// Now you can do whatever you want with LinearLayout

Dialog.OnShowListener showListener = new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {

View.OnClickListener hideListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
linearLayout.setVisibility(View.INVISIBLE);

}
};

View.OnClickListener unHideListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
linearLayout.setVisibility(View.VISIBLE);

// Hiding LinearLayout but this doesn't
// dismiss the dialog if you want
// call dialogInterface.dismiss();
}
};

// Overriding AlertDialog's Button because we don't want it
// to dismiss in every click
Button hide = ((AlertDialog) dialogInterface).getButton(AlertDialog.BUTTON_POSITIVE);
Button unhide = ((AlertDialog) dialogInterface).getButton(AlertDialog.BUTTON_NEGATIVE);
hide.setOnClickListener(hideListener);
unhide.setOnClickListener(unHideListener);
}
};

AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setView(view)
.setPositiveButton("Hide", null)
.setNegativeButton("Unhide", null);

AlertDialog dialog = builder.create();
dialog.setOnShowListener(showListener);
dialog.show();

Subscribing multiple views to A views onclick and visibility change RxAndroid

The most closest thing looks like this:

 RxView.globalLayouts(info_overlay)
.map { info_overlay.visibility }
.distinct()
.subscribe { newVisibility ->
info_overlay.run {
(0 until childCount)
.map(this::getChildAt)
.forEach { view -> view.visibility = newVisibility }
}
}

In case if you don't need to change all children views use method as following:

 RxView.globalLayouts(info_overlay)
.map { info_overlay.visibility }
.distinct()
.subscribe { newVisibility ->
info_overlay_child_take_a_helfie.visibility = newVisibility
...
}

Explaining. I've taken idea from this answer https://stackoverflow.com/a/32778292/4727432

myView.setTag(myView.getVisibility());
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int newVis = myView.getVisibility();
if((int)myView.getTag() != newVis) {
myView.setTag(myView.getVisibility());
//visibility has changed
}
}
});

Roughly speaking, code aboves does the same as RxView.globalLayouts(). After that I map value to view visibility. I've added distinct to make invoking subscribe only in case if visiblity changes.

Change view visibility for each item inside a RecyclerView within a Fragment when a text is clicked

First you need to add a new property to your BagItem. We'll called it editMode.

class BagItem {
boolean editMode;
}

Initially editMode is false. When the user push edit button, you need to change editMode to true. Make sure that your mBagList is set to public. Next you need to notify the recycler view adapter that the data was changed.

for (BagItem bagItem: bagItemsAdapter.mBagList) {
bagItem.editMode = true;
}
bagItemsAdapter.notifyDataSetChanged();

You also need to update the visibility of removeBagItem according to editMode value.

holder.removeBagItem.setVisibility(currentItem.editMode ? View.VISIBLE : View.GONE);

How to recover view from View.gone. setVisibility(View.VISIBLE) not working after using 'android:visibility=gone' in xml

1.View Visibility not working

The Visibility is not working because the view is not rendered initially. Remove the visibility gone in the xml and handle the visibility fully in the adapter class. In the 'assess_list_layout' linerlayout height can be hardcode because inside this layout the listview height is already hardcoded. You can hardcode to 300 and check. This way will help the view to get the initial rendering.

2. Scroll issue

While scrolling the already visible 'assess_list_layout' view might be not visible. This is because we need to handle the visibility, this handling is similar to checkbox selection handling in listview. Hope the Course class is model class, in that add a another property named isSelected as boolean and set the default value to false. Please refer below the course class,

Course Class

public class Course {
private boolean isSelected = false;

public boolean isSelected() {
return isSelected;
}

public void setSelected(boolean selected) {
isSelected = selected;
}

}

please refer the below code changes in the adapter class.

    public class CourseListAdapter extends ArrayAdapter<Course> {
private static final String TAG = "CourseListAdapter";

private Context context;
int mResource;

public CourseListAdapter(@NonNull Context context, int resource, @NonNull ArrayList<Course> objects) {
super(context, resource, objects);
this.context = context;
mResource = resource;
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
// get info
String course_code = getItem(position).getCourseCode();
Double course_grade = getItem(position).getCurrentGrade();

// make inflater and inflate the layout
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(mResource, parent, false);


TextView tv_course_code = v.findViewById(R.id.course_adapter_course_code);
TextView tv_course_title = v.findViewById(R.id.course_adapter_course_title);

//My Change
// expand the view to include a new fragment
LinearLayout assess_list_layout = view.findViewById(R.id.assess_list_layout);

// get the list view and add each course to the course view
ListView assessment_list_view = (ListView) view.findViewById(R.id.course_adapter_assess_list);

assess_list_layout.setVisibility(View.GONE);

if (getItem().get(position).isSelected()) {
assess_list_layout.setVisibility(View.Visible);
AssessmentListAdapter assessAdapter = new AssessmentListAdapter(getContext(), R.layout.assessment_adapter_view, getItem(position).getAssessmentList(), getItem(position));
assessment_list_view.setAdapter(assessAdapter);
}
//My Change

tv_course_code.setText(course_code);
tv_course_title.setText(String.valueOf(course_grade));

// add on click to each list view element
LinearLayout layout = v.findViewById(R.id.course_adapter_layout);
layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i(TAG, "List view element has been clicked " + course_code);

//My Change
getItem().get(position).setSelected(true);
//My Change
assess_list_layout.setVisibility(View.VISIBLE);


AssessmentListAdapter assessAdapter = new AssessmentListAdapter(getContext(), R.layout.assessment_adapter_view, getItem(position).getAssessmentList(), getItem(position));
assessment_list_view.setAdapter(assessAdapter);
}
});

return v;
}
}

I have commented as My Change to find the difference in the code.

View visibility state loss when resuming activity with previously started Activity transition

To give a feedback for this old question by me.

I filed a bugticket to google: https://issuetracker.google.com/issues/112158868, but they are not able to fix this, since they prioritize other bugs.

My solution is here is to switch to a single activity concept with jetpack navigation (https://developer.android.com/jetpack/compose/navigation).

So i do the transitions with fragments now.

Thank you for your responses.

Android: Changing visibility of a view in recyclerView

Move the click logic away from the ViewHolder:

class MyViewHolder extends RecyclerView.ViewHolder {
TextView message;
Button button;
public MyViewHolder(View itemView) {
super(itemView);
message = (TextView) itemView.findViewById(R.id.message);
button = (Button) itemView.findViewById(R.id.button);
}
}

and place it inside the method onBindViewHolder of your adapter:

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.button.setVisibility(View.GONE);
holder.message.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.button.setVisibility(View.VISIBLE);
}
});
}

ViewHolder is reused by the RecyclerView, that's why you are seeing the button visible in other rows.

Android: why setVisibility(View.GONE); or setVisibility(View.INVISIBLE); do not work

I see quite a few things wrong. For starters, you don't have your magic button defined and there is no event handler for it.

Also you shouldn't use:

dp2.setVisibility(View.GONE);
dp2.setVisibility(View.INVISIBLE);

Use only one of the two. From Android documentation:

View.GONE This view is invisible, and it doesn't take any space for
layout purposes.

View.INVISIBLE This view is invisible, but it still
takes up space for layout purposes.

In your example, you are overriding the View.GONE assignment with the View.INVISIBLE one.


Try replacing:

final DatePicker dp2 = new DatePicker(this)

with:

DatePicker dp2 = (DatePicker) findViewById(R.id.datePick2);  

Similarly for other widgets:

    public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

final DatePicker dp2 = new DatePicker(this);
final Button btn2 = new Button(this);
final Button magicButton = new Button(this);
final TextView txt2 = new TextView(TestActivity.this);

dp2.setVisibility(View.GONE);
btn2.setVisibility(View.GONE);
btn2.setText("set Date");

btn2.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
txt2.setText("You selected "
+ dp2.getDayOfMonth() + "/" + (dp2.getMonth() + 1)
+ "/" + dp2.getYear());
}
});

magicButton.setText("Magic Button");
magicButton.setOnClickListener(new View.OnClickListener()
public void onClick(View arg0) {
dp2.setVisibility(View.VISIBLE);
btn2.setVisibility(View.VISIBLE);
}
});

ll.addView(dp2);
ll.addView(btn2);
ll.addView(magicButton);
ll.addView(txt2);

setContentView(ll);
}


Related Topics



Leave a reply



Submit