vaadin viewchangelistener change newView - java

I try to change the newView of a navigation if the user is not authenticated and the newView is an instance of SecuredView. My approach was to check inside the beforeViewChange method if the constraints are given.
public boolean beforeViewChange(ViewChangeEvent event) {
if (event.getNewView().getClass().isInstance(SecuredView.class) && VaadinService.getCurrentRequest().getUserPrincipal() == null) {
event.getNavigator().navigateTo("login");
return false;
}
return true;
}
}
But that will result in a endless loop of redirection... How can i change the newView and stop the current navigation event?

1) If your View is not 'a correct view' it will end up in an endless loop. Try this simple view:
public class SecuredView extends VerticalLayout implements View {
public SecureView() {
addComponent(new Label("Secured View"));
}
#Override
public void enter(ViewChangeEvent event) {
}
}
2) Your if statement needs to be changed:
instead of:
event.getNewView().getClass().isInstance(SecuredView.class)
write:
SecuredView.class.isInstance(event.getNewView());

Related

Searchview clear focus on hide keyboard

The user presses the hide keyboard button or the back button.
So I need to clear focus on the SearchView when the user is hiding the keyboard.
I tried this but it's not working. focus remains when the user hides the keyboard.
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
searchView.clearFocus();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
app.requests.getApi().search(newText).enqueue(SearchFragment.this);
return false;
}
});
and this:
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
app.functions.logWrite("has focus to searchview");
} else {
//code
}
}
});
Okay so try this it needs the use of a library unfortunately but it makes it easier.
In your build.gradle: add this:
dependencies {
implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:3.0.0-RC2'
}
Register for the keyboard events using KeyboardVisibilityEvent library like this in the fragment/class where SearchView is declared:
KeyboardVisibilityEvent.setEventListener(
getActivity(),
new KeyboardVisibilityEventListener() {
#Override
public void onVisibilityChanged(boolean isOpen) {
if (!isOpen) {
View focusedView = getWindow().getCurrentFocus();
if (focusedView != null && focusedView instanceof SearchView) { // does SearchView have focus?
searchView.clearFocus();
}
}
}
});
searchView.clearFocus(); works on the assumption you have another focusable view in the hierarchy, if not add this to your fragments layout:
android:focusableInTouchMode="true"
Alternatively simply call focus(); on any other view element you want to receive focus.
This is what I use for handling back button clicks for SearchView, by Overriding onBackPressed()
#Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
ANY_VIEW_IN_YOUR_LAYOUT.requestFocus();
} else
super.onBackPressed();
}
Hope this helps. Feel free to ask for clarifications...

view visibility check in fragment inside viewpager and tablayout in Android

I have a weird problem.
Achieved
I have 4 Fragments in a ViewPager attached with TabLayout. The first one is QR-code Scanner, which shows a camera. I wanted to start camera only when the Fragment is visible. For this, I override the Fragment's method setUserVisibleHint.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser) {
checkPermissionForCamera(); //it checks permission and start camera
} else {
stopCamera();
}
}
And it's working absolutely fine.
Desired
Now, what I want to achieve is that when Fragment is not visible (or is being visible by scrolling), it shows a view with background over camera, so that instead of camera, that cover is visible. Like image below.
For it, I edited startCamera and stopCamera, now it looks like below,
public void startCamera() {
if(cameraCover != null)
cameraCover.setVisibility(View.GONE);
isCameraStarted = true;
mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
mScannerView.startCamera();
}
public void stopCamera() {
if(cameraCover != null)
cameraCover.setVisibility(View.VISIBLE);
if(mScannerView != null) {
isCameraStarted = false;
mScannerView.stopCamera();// Stop camera on pause
mScannerView.stopCameraPreview();// Stop camera preview
}
}
But the gray cover is only visible for the first time, rest of the time I get the camera opened with view on which it's scrolled, like below.
I've also tried to override onPageScrolled of OnPageChangeListener, but with no luck. Here's what I've done.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 0) {
if(positionOffset > 0.7) {
fragment = adapter.getItemAtPosition(0); //fragment is at zero
if(fragment != null) {
if(fragment instanceof ScanQRFragment) {
((ScanQRFragment) fragment).stopCamera();
}
}
}
}
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Try either of the following ways :
1- override setMenuVisibility :
#Override
public void setMenuVisibility(final boolean visible) {
if (visible) {
//start camera preview
}
super.setMenuVisibility(visible);
}
2- Check yourFragment.isResumed() instead of isVisible()

using switch statement to handle onBackPressed() in fragments

i am trying to handle the onBackPressed diferently for every fragment. for this i want to use a switch statement with cases dependedn on the fragment that is currently showing.
in my Main i have. but dont know what to use in the switchstatement.
public class MyActivity extends Activity
{
#Override
public void onBackPressed(){
super.onBackPressed();
switch(........){
case (1):
Fragment1.onBackPressed();
case (2):
Fragment2.onBackPressed();
}
}
in my fragments:
public class Fragment1 extends Fragment
{
//My created method
public static void onBackPressed()
{
// make it do what you want.
}
}
so my question, how can i use a switchstament where de cases are depended on what fragment is showing at this moment.
Don't use such switch in single onBackpressed of activity but you can get the key event of each fragment object and do like this,
fragment.getView().setFocusableInTouchMode(true); //Don't miss this line
fragment.getView().setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
//Do what you want
return true;
}
return false;
}
} );
In on onBackPressed(). You can check current visible Fragment
public class MyActivity extends Activity
{
#Override
public void onBackPressed(){
if(yourFragment1.isVisible()) {
...
}else if(yourFragment2.isVisible(){
...
}
}
}

Is there any method to find out the display-changing events of android smartphone?

I'm a student of Yonsei graduate school, Korea.
I want to make a simple application that measures an time interval - between
touching the screen and display-updating.
I found that following method catch the touching event.
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if(event.getAction() == MotionEvent.ACTION_DOWN ){
...
Now I'm searching the Android APIs, but I coudn't find the method which catches
display-updating event. If you have any information about this problem,
please show mercy to me. Thank you.
Try adding a ViewTreeObserver.onDrawListener to a view in your Activity's content view. You can make a class that implements the that interface. When you get the touch event, call a method on your draw listener to record the time of the next draw event.
private MyDrawListener myDrawListener = new MyDrawListener();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
findViewById(...).getViewTreeObserver().addOnDrawListener(myDrawListener);
}
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
myDrawListener.recordNextDrawTime();
}
}
public static class MyDrawListener implements ViewTreeObserver.OnDrawListener {
private boolean recordNextDrawTime;
public void recordNextDrawTime() {
recordNextDrawTime = true;
}
#Override
public void onDraw() {
if (recordNextDrawTime) {
Log.d("MyDrawListener", "Draw time = " + System.currentTimeMillis());
recordNextDrawTime = false;
}
}
}

Android viewflow validation

Currently I have a few forms using this horizontal sliding view.
https://github.com/pakerfeldt/android-viewflow
Is their a way to prevent the user from sliding to the next screen when the form is filled in incorrectly? e.g. disable the horizontal scroll.
Yes, change this portion of your copy of the ViewFlow
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
....
case MotionEvent.ACTION_MOVE:
//Add an if / else here that validates your input.
//If it is incorrect don't let the rest of the code that is here do the scrolling.
I had the same problem, just added a Boolean variable and a setter and getter:
...
public class ViewFlow extends AdapterView<Adapter> {
private Boolean flagAllowScroll = false;
//the rest of the code
...
public Boolean getFlagAllowScroll() {
return flagAllowScroll;
}
public void setFlagAllowScroll(Boolean flagAllowScroll) {
this.flagAllowScroll = flagAllowScroll;
}
And the put it on the onTouchEvent function
...
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (!getFlagAllowScroll())
return false;
//the rest of the code
...
And other in the onInterceptTouchEvent function
...
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!getFlagAllowScroll())
return false;
//the rest of the code
...
And change it of this way:
...
//Allows changes
viewFlow.setFlagAllowScroll(true);
...
//Doesn't Allows changes
viewFlow.setFlagAllowScroll(false);
...
I hope this works for you =)

Categories