Hide one View depending on Visibility of another - android

I'm experimenting a little bit with RxJava, and I have stuck in a what sounds to be a simple task.
Let's say we have two Views, View1 and View2.
Right now I'm trying to accomplish that, when View1 is visible, the View2 needs to be gone.
P.S. I'm searching for RxJava solution.
Edit 2
As I mentioned in comment, I was trying to use RxView.visibility().
So therefor I did not publish any code, because none of it worked and it's mostly one line.
As for the down voters, at least try to mention what you don't like about the question, so I could improve it.

Try:
RxView.layoutChangeEvents(view1)
.subscribe(ignore -> {
if (view1.getVisibility() == View.VISIBLE) {
view2.setVisibility(View.GONE);
} else {
view2.setVisibility(View.VISIBLE);
}
}, throwable -> new Exception(throwable));

I don't really understand what you're trying to do in your experiments, I think in your case you don't need RxJava, it's usual if/else condition, but I've thought this small example, which maybe helps you.
I have only EditText and Button as Views:
RxTextView.textChanges(editText)
.map(text -> !TextUtils.isEmpty(text))
.subscribe(RxView.visibility(button));
It'll show the button only if user inputs some text.

Here's a better solution if you're using RxBinding library using the RxView's visibility() function:
view2.visibility(View.GONE).accept(view1.getVisibility() == View.VISIBLE);

Related

UiScrollable scrollIntoView stops just before scrolling into view

I have created the following wrap of UiScrollable for android testing:
protected fun UiScrollable.ensureScrolledIntoView(elementToScrollTo: UiObject) {
val elementPresent = scrollIntoView(elementToScrollTo)
if (!elementPresent) {
Assert.fail("Expected element ${elementToScrollTo.selector} not found in scroll view")
}
}
I believe the wrapper itself is not the problem, but sometimes the scrollIntoView fails to make the last needed scroll swipe. Best is to demonstrate with example:
Gives the error:
java.lang.AssertionError: Expected element
UiSelector[CLASS=android.widget.LinearLayout, DESCRIPTION=May,
CHILD=UiSelector[TEXT=7,
RESOURCE_ID=com.maypackage.android:id/calendar_day_text_view]] not
found in scroll view
And it was, obviously tasked to scroll to May 7th.
The same thing sometimes happens when I search for a date that will be found with up scroll: the method returns just one scroll short and the element is not found.
Has anyone encountered such problem? How to overcome it?
EDIT
After much more experimentation I found out the issue to be elements on the screen consuming certain scrolling attempts. This is most easily experienced in case of floating buttons, but the situation of the question shows more obscure example of the same. In most cases it turned out that setSwipeDeadZonePercentage on the UiScrollable did the trick for me. This methods tells the scrollable that there is certain area in which no swiping attempts should be made. This solved the issues in cases of overflow buttons. For the more obscure cases I use the method below, which is still not guaranteed to work all the time, but is stable in my cases.
OLD, original answer:
Eventually, after much trials I found out that the framework error is more generic and does not necessary trigger a stop one swipe before the element is in the view. Frankly, I believe the problem is with the unstable behavior of scrollForward method which is used internally in the scrollIntoView method. Eventually I re-wrote my method as follows:
protected fun UiScrollable.ensureScrolledIntoView(elementToScrollTo: UiObject) {
// this method used to use scrollIntoView, but it proved unstable
if (elementToScrollTo.exists()) return
while (scrollBackward()) {
// no body needed
}
// very complex construct, because scroll forward seems to return false on first call
var consecutiveFailingScrolls = 0
while (consecutiveFailingScrolls < 2) {
if (elementToScrollTo.exists()) return
if (!scrollForward()) {
consecutiveFailingScrolls++
} else {
consecutiveFailingScrolls = 0
}
}
Assert.fail("Expected element ${elementToScrollTo.selector} not found in scroll view")
}
This is basically trying to address the framework instability and, up to the moment it has not failed me. By the way, I suspect the instability of scrollIntoView manifests only when we are scrolling lazily loading components like recycler views. For the moment I intend to continue using the library methods for non-lazy loading lists and see if more errors are encountered.

Preventing double clicking in components throughout entire app

I know how to prevent double-clicking on a component. What I want to know if there is some way to avoid this behaviour "by default" when adding a component. Do I have to go every single item that can be clicked in an app and write the same code for every single component?
I know I could subclass, say, Button class, write the code for preventing double-clicking there, and only use my Button class in the app. What is the point of it? Why isn't something like that in the default Android Button class? I haven't seen any intended double-clicking behaviour in ANY app. Do I have to write a subclass of every single View that is susceptible of being clicked in order to prevent this? is there something I am missing?
Just to clarify, my question is about something like disableDoubleClick() method or something like that. I already said I know how to prevent this, but is a bit of a hassle to do it for every single clickable item in an app.
You can use Kotlin with its extensions in conjunction with reactive bindings of RxJava.
for the general view it will look something like:
fun View.clickWithDebounce(debounceTime: Long = 600L, action: () -> Unit): Disposable =
RxView.clicks(this)
.debounce(debounceTime, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { action() }
Use it like this:
button.clickWithDebounce{
//do stuff
}
textView.clickWithDebounce{
//do other stuff
}
imageView.clickWithDebounce{
//do some completely unrelated with the previous two stuff
}
floatingButton.clickWithDebounce(100000000){
//do some stuff and wait 100000 seconds before the next click
}
For more info: Kotlin Extensions, RxJava RxBinding
Hope it helps.

xamarin mutli selection listview

It's been a while that i'm trying to get an anwser to my problem, but i didn't find it... So i'm searching for your help.
I work on xamarin to make an android application but i dont use Xamarin.Forms (i would have used it, if i knew it when i begin the project
I'll directly to the point, if you have some question, just ask me.
So i got a Listview where i can select 2 or more items :
private void _listViewIntervention_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
_intervention[e.Position].IsSelected = !_intervention[e.Position].IsSelected;
if (_intervention[e.Position].IsSelected)
e.View.SetBackgroundColor(Android.Graphics.Color.Rgb(255, 127, 127));
else
e.View.SetBackgroundColor(Android.Graphics.Color.Rgb(230, 230, 230));
_numberInterventionSelected.Text = _intervention.FindAll(elem => elem.IsSelected == true).Count().ToString();
}
That thing work but if i have a listview with 20 items i.e and i select 3 items, if i scroll the listview, everything will be disturb and my 3 highlighted rows won't be anymore and the highlight will be on another row that i've never select.
I think that not that evident and it might be blur.
IMO i'm not changing the good thing when i do the "e.View.SetBackgroundColor" but i've try lot of thing that never worked.
I might not going the best way to do what i want to do btw.
The result i want is when i scroll the listview, nothing change so i can select the first and the last item of the listview i.e.
I search again in my side but i count a little on you know...
Thanks for reading and have a good day !
I have already getting same problem after lot of search and find the solution
In Xamarin custom adapter remove ViewHolder System it's working fine after removing Holder system

Is there an Android design pattern to handle multiple fragments in a single activity?

I inherited some code at work and I have a question about some implementation. The application I'm working on has an Activity that contains about 15 different fragments. The logic in the Activity handling these fragments can roughly be summarized with the following pseudocode:
if (button_1 selected) {
load fragment_1;
} else if (button_2 selected) {
load fragment_2;
} else if (button_3 selected) {
load fragment_3;
} ...and so on x15ish
My question is: does there exist some kind of Android design pattern to handle situations like this? The code works; however, I don't feel too comfortable with a giant if/else or case statement. I saw this question and it seems very similar to the problem that I'm having. I did quite a bit of searching on the internet but I haven't found examples or best practices for this kind of scenario.
If someone can point me in the right direction or have some suggestions; that'd be awesome. Thanks!
For each button in your layout you can assign a method in your activity:
<Button
...
android:onClick="startFragmentOne" />
Then implement those methods:
public void startFragmentOne(View view) {
//TODO
}
You should not check which button has been selected but rather use the button's onClickListener to select the correct fragment.
buttonForFragment1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// select fragment 1 here
}
});
In regards to the question, this is not a level of design patterns but rather implementation details (idioms) and you correctly recognized your code as a smell and I think one possible solution which does not qualify as a pattern is the code above.

Hide/show AChartEngine series using checkboxes

Basically I have a chart with four different series, that by default shows all four of them at the same time. I want to allow the user to hide and/or show them again as he pleases by marking checkboxes.
I found a similar question here and followed both the advices given, but it didn't work. Here is what one of my checkboxes looks like now:
checkBox1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(((CheckBox)v).isChecked()){
multiRenderer.addSeriesRenderer(distanceRenderer);
// distanceRenderer.setColor(Color.parseColor("#990000")); //(making transparent method)
}
else{
//distanceRenderer.setColor(Color.TRANSPARENT); //(making transparent method)
multiRenderer.removeSeriesRenderer(distanceRenderer);
}
}
});
The idea is to when I uncheck the checkbox, I will hide that one renderer, when I check it again, it will be added again.
In the suggestions of the thread I linked to, they said to remove all renderers and then reenter the ones that aren't supposed to be hidden. I also tried this, but to no avail. The third option was simply to change the color to transparent whenever I wanted it to disappear, this also didn't work.
I debugged it, and it is getting in the conditions correctly, but nothing happens. Is there something I need to call that I've missed?
Thanks!
Edit: I don't know if this somehow helps, but I also tried to call the XYMultipleSeriesDataset's function repaint(). This caused an IllegalStateException, soooo.... Still no good...
Try this for hide purpose :
r.setColor(Color.TRANSPARENT);
mChartView.repaint();
where r is XYSeriesRenderer .

Categories

Resources