Calling a method in the main activity from class adapter - firebase-realtime-database

Here is my code in my AddClassAdapter recylerview using firebase below on "onBindViewHolder":
holder.editBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
UserClasses userClasses = new UserClasses();
userClasses.openEditClassDialog();
}
});
And here is the "openEdiClassDialog" method in my main activity:
public void openEditClassDialog(){
UserClassEditDialog userClassEditDialog = new UserClassEditDialog();
userClassEditDialog.show(getSupportFragmentManager(),"user class dialog");
}
My problem is, If I clicked the edit button of an item in the recylerview adapter, this error shows in my logcat:
java.lang.IllegalStateException: FragmentManager has not been attached to a host. at androidx.fragment.app.FragmentManager.enqueueAction
At this moment, I am finding a solution to try, but I am expecting that if I clicked the edit button, a dialog will pop up.

Related

xamarin.android webview evaluatejavascript It does not return any value at all

I have a fundamental problem that I can not really understand where the problem comes from.
I am designing a project by xamarin.android webview.
Now I need to run a Java function in Web View and check the return value in a if function.
I searched all the websites and in all of them I got the following code:
In Main Activity Class:
public class MainActivity : AppCompatActivity
{
WebView web_view;
.
.
.
Define web_view public in class
In OnCreate :
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
web_view = FindViewById<WebView>(Resource.Id.webview);
web_view.Settings.JavaScriptEnabled = true;
web_view.Settings.BuiltInZoomControls = true;
web_view.Settings.AllowContentAccess = true;
web_view.SetWebViewClient(new HelloWebViewClient());
web_view.LoadUrl("https://www.example.com");
}
In Back Key Press:
public override bool OnKeyDown(Android.Views.Keycode keyCode, Android.Views.KeyEvent e)
{
if (keyCode == Keycode.Back)
{
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
{
JavascriptResult jsr = new JavascriptResult();
string strjs = "closePackageDetails();";
web_view.EvaluateJavascript(strjs, jsr);
string rrr = jsr.strResult;
Toast.MakeText(this, "message send:" + rrr, ToastLength.Long).Show();
}
else
{
Toast.MakeText(this, "android version less 4.4" , ToastLength.Long).Show();
}
}
}
On JavascriptResult Class (separate on C# Class Palaced in MainActivity in Root directory)
namespace webviewapp
{
class JavascriptResult : Java.Lang.Object, IValueCallback
{
public string strResult;
public void OnReceiveValue(Java.Lang.Object result)
{
Toast.MakeText(Android.App.Application.Context, "رسیدن نتیجه احضار شد", ToastLength.Long);
strResult = ((Java.Lang.String)result).ToString();
}
}
}
<>
Everything looks right and the program is debugged without error and the APK file is created successfully.
After installing the program on the mobile phone and running it, the web page is loaded and everything looks good.
By touching the back button, the JavaScript function is executed correctly and the result is visible in Web View. But the result, which is a boolean value, is not returned.
In fact, the OnReceiveValue procedure does not work.
The variable 'rrr' always displays an null value.
Where it went wrong really puzzled me?
It is happening because the callback is executed later than the next line ,so the variable 'rrr' is always null.
Add the breakpoint at OnReceiveValue and the line string rrr = jsr.strResult; to check it .
Just do the next thing directly in the method OnReceiveValue in the callback class.

show a login page before moving to main app in xamarin.android

so I'm trying to make an android app that starts with a login page (that I thought could be a dialog fragment) and if the user's credentials are correct, then he'll be directed to the main app that is supposed to be a navigation drawer app. I tried to use the dialog fragment but I didn't know how to set it to appear at the very beginning. what should I do?
You should create a Activity as a MainLauncher, Activity you can use a blank Layout.xml like following code, then pop a DialogFragment like following code. Note: you should add MainLauncher = true,NoHistory =true in your Activity attribute. NoHistory =true will make the back button navigate to the desktop.
namespace App2
{
[Activity(Label = "LoginActivity", Theme = "#style/AppTheme.NoActionBar",MainLauncher = true,NoHistory =true)]
public class LoginActivity : AppCompatActivity, OnLoginInforCompleted
{
public void inputLoginInforCompleted(string userName, string passWord)
{
//You can get the username and password here
StartActivity(new Intent(this,typeof(MainActivity)));
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.LoginLayout);
MyDialogFragment dialogFragment = new MyDialogFragment();
dialogFragment.setOnLoginInforCompleted(this);
dialogFragment.Cancelable = false;
var SupportFragmentManager = this.FragmentManager;
dialogFragment.Show(SupportFragmentManager, "dialog");
}
}
}
I achieve the a callback interface OnLoginInforCompleted, If User click the Login Button, will navigate to the navigation drawer page.
public interface OnLoginInforCompleted
{
void inputLoginInforCompleted(String userName, String passWord);
}
Here is code about MyDialogFragment .
public class MyDialogFragment : DialogFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.layout3, container, false);
Button button = view.FindViewById<Button>(Resource.Id.button1);
EditText MyeditText1 = view.FindViewById<EditText>(Resource.Id.editText1);
EditText MyeditText2 = view.FindViewById<EditText>(Resource.Id.editText2);
button.Click += delegate {
//set the data to the loginpage
mOnLoginInforCompleted.inputLoginInforCompleted(MyeditText1.Text.ToString(), MyeditText2.Text.ToString());
Dismiss();
};
return view;
}
//set for Callback
private OnLoginInforCompleted mOnLoginInforCompleted;
public void setOnLoginInforCompleted(OnLoginInforCompleted onLoginInforCompleted)
{
mOnLoginInforCompleted = onLoginInforCompleted;
}
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
return base.OnCreateDialog(savedInstanceState);
}
}
Here is running GIF.
Here is my demo, you can refer to it.
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/App2.zip

Vaadin Grid middle mouse click

I'm trying to emulate normal browser behaviour in my vaadin grid, which includes middle mouse click to open in a new tab:
addItemClickListener(e -> {
boolean newTab = e.getMouseEventDetails().getButton() == MouseEventDetails.MouseButton.MIDDLE || e.getMouseEventDetails().isCtrlKey();
//open in window or new tab
});
However, the middle mouse button is not registered by vaadin. How could I get this to work?
That feature was included in vaadin-grid (which goes into Vaadin 10) and will not work in Vaadin 8.
For Vaadin 8, you can either intercept the event with some client-side extension, or use a ComponentRenderer for adding a Panel to each component (which works, but is not ideal because it degrades performance):
grid.addColumn(item->{
Panel p = new Panel(item.getName());
p.setStyleName(ValoTheme.PANEL_BORDERLESS);
p.addClickListener(ev->{
System.out.println(ev.getButtonName());
});
return p;
}).setRenderer(new ComponentRenderer());
A client-side extension, on the other hand, allows listening to javascript events (such as MouseEvent) and triggering a server event in response. Creating a extension is quite a complex topic (since it uses a part of the API that is normally hidden from the developer) but it allows direct access to rendered DOM, which is not possible otherwise.
The following resources from the documentation may give you a starting point:
Creating a component extension (which describes a simple extension with Java code only) and Integrating JavaScript Components and Extension (which explains how to add native JavaScript code to your extension).
How I solved the problem in my specific case:
Server side:
public class MyGrid<T> extends Grid<T> {
public MyGrid(String caption, DataProvider<T, ?> dataProvider) {
super(caption, dataProvider);
MiddleClickExtension.extend(this);
}
public static class MiddleClickExtension<T> extends AbstractGridExtension<T> {
private MiddleClickExtension(MyGrid<T> grid) {
super.extend(grid);
registerRpc((rowKey, columnInternalId, details) -> grid.fireEvent(
new ItemClick<>(grid, grid.getColumnByInternalId(columnInternalId), grid.getDataCommunicator().getKeyMapper().get(rowKey), details)),
MiddleClickGridExtensionConnector.Rpc.class);
}
public static void extend(MyGrid<?> grid) {
new MiddleClickExtension<>(grid);
}
#Override
public void generateData(Object item, JsonObject jsonObject) {
}
#Override
public void destroyData(Object item) {
}
#Override
public void destroyAllData() {
}
#Override
public void refreshData(Object item) {
}
}
}
Client side:
#Connect(MyGrid.MiddleClickExtension.class)
public class MiddleClickGridExtensionConnector extends AbstractExtensionConnector {
#Override
protected void extend(ServerConnector target) {
getParent().getWidget().addDomHandler(event -> {
if (event.getNativeButton() == NativeEvent.BUTTON_MIDDLE) {
event.preventDefault();
CellReference<JsonObject> cell = getParent().getWidget().getEventCell();
getRpcProxy(Rpc.class).middleClick(cell.getRow().getString(DataCommunicatorConstants.KEY), getParent().getColumnId(cell.getColumn()),
MouseEventDetailsBuilder.buildMouseEventDetails(event.getNativeEvent(), event.getRelativeElement()));
}
}, MouseDownEvent.getType());
}
#Override
public GridConnector getParent() {
return (GridConnector) super.getParent();
}
public interface Rpc extends ServerRpc {
void middleClick(String rowKey, String columnInternalId, MouseEventDetails details);
}
}

unable to click on Image Button

how do i click on the mage button
i tried with xpath and id below are the mentioned code that i had tried
driver.findElementById("btn_google").click();
// driver.findElementByName("Login with Google+").click();
//driver.findElementByXPath("//android.widget.ImageButton[#content-desc='Login with Google+',#resource-id,'btn_google']").click();
// driver.findElementByXPath("//android.widget.Button[contains(#resource-id,'btn_google') and #content-desc,'Login with Google+']").click();
// driver.findElementByXPath("//*[#class='android.widget.ImageButton' and #resource-id='btn_google']").click();
//driver.findElementByName("Login with Google+").click();;
WebElement element=driver.findElementByXPath("//*[#class='android.widget.ImageButton' and #resource-id='btn_google']");
TouchAction action = new TouchAction(driver);
action.longPress(element).release().perform();
//driver.findElement(By.xpath("//android.widget.ImageButton[#content-desct='Login with Google+']")).click();
// WebElement googlebutton= driver.findElementByXPath("//android.widget.ImageButton[#resource-id='com.zipgo.customer:id/btn_google']");
// googlebutton.click();
You can simply find the id of that imagebutton like:
googleImageButton=(ImageButton)findViewById(R.id.googleImageButton);
And now you can call a listener method for any operation, for eg:
googleImageButton.setOnClickListener(googleImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//action
}
});)
try this
driver.findElementByXpath("//android.widget.ImageButton[#index='0']").click();

How to start a file download in vaadin without button?

I know that it is really easy to create a FileDownloader and call extend with a Button. But how do I start a download without the Button?
In my specific situation right now I have a ComboBox and the file I'd like to send to the user is generated after changing its value, based on the input. The file should be sent immediately without waiting for another click. Is that easily possible?
Thanks
raffael
I found a solution myself. Actually two.
The first one uses the deprecated method Page.open()
public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();
public DownloadComponent() {
cb.addValueChangeListener(this);
cb.setNewItemsAllowed(true);
cb.setImmediate(true);
cb.setNullSelectionAllowed(false);
setCompositionRoot(cb);
}
#Override
public void valueChange(ValueChangeEvent event) {
String val = (String) event.getProperty().getValue();
FileResource res = new FileResource(new File(val));
Page.getCurrent().open(res, null, false);
}
}
The javadoc here mentions some memory and security problems as reason for marking it deprecated
In the second I try to go around this deprecated method by registering the resource in the DownloadComponent. I'd be glad if a vaadin expert comments this solution.
public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();
private static final String MYKEY = "download";
public DownloadComponent() {
cb.addValueChangeListener(this);
cb.setNewItemsAllowed(true);
cb.setImmediate(true);
cb.setNullSelectionAllowed(false);
setCompositionRoot(cb);
}
#Override
public void valueChange(ValueChangeEvent event) {
String val = (String) event.getProperty().getValue();
FileResource res = new FileResource(new File(val));
setResource(MYKEY, res);
ResourceReference rr = ResourceReference.create(res, this, MYKEY);
Page.getCurrent().open(rr.getURL(), null);
}
}
Note: I do not really allow the user to open all my files on the server and you should not do that either. It is just for demonstration.
Here is my work-around. It works like a charm for me. Hope it will help you.
Create a button and hide it by Css (NOT by code: button.setInvisible(false))
final Button downloadInvisibleButton = new Button();
downloadInvisibleButton.setId("DownloadButtonId");
downloadInvisibleButton.addStyleName("InvisibleButton");
In your theme, add this rule to hide the downloadInvisibleButton:
.InvisibleButton {
display: none;
}
When the user clicks on menuItem: extend the fileDownloader to the downloadInvisibleButton, then simulate the click on the downloadInvisibleButton by JavaScript.
menuBar.addItem("Download", new MenuBar.Command() {
#Override
public void menuSelected(MenuBar.MenuItem selectedItem) {
FileDownloader fileDownloader = new FileDownloader(...);
fileDownloader.extend(downloadInvisibleButton);
//Simulate the click on downloadInvisibleButton by JavaScript
Page.getCurrent().getJavaScript()
.execute("document.getElementById('DownloadButtonId').click();");
}
});

Resources