I have one Edit Text, 5 buttons and a Webview. Webview load url when user type url in edit text and tap Go button or hit Enter on soft keyboard.
I have three problems here.
1-WebView loads website for example "www.google.com" but soft keyboard does not hide itself. I want to hide it like other browser do.
2-When user open a specific url and then try to remove it from Edit Text to open a different url, webview start loading that incomplete url and get focus automatically on every letter removing. For example user loads "www.google.com" then he try to remove url from end and as he remove "m", webview try to load "www.google.co" then edit text is out of focus and webview stole focus from it then user have to tap in edit text again to remove url but it tries to load after every letter removing. I need Webview to load url only when user tap on Go button or hit Enter on soft keyboard.
Update (forgot to add third problem, here it is)
3-Where can i check when WebView CanGoBack and CanGoForward because i want to set visibility of Back and Forward buttons to false at startup and enabled these two buttons while they CanGoBack and CanGoForward. Where should i put my piece of code to check these conditions?
I hope you guys can understand what i am trying to say. Sorry for my poor english.
Here is my xml code.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="13"
tools:context="com.hbss.chatapp.rashidfaheem.hybridsoftwaresolutions.rashidfaheem.youseebrowser.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:weightSum="4"
>
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/etUrl"
android:layout_weight="3"
/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="GO"
android:id="#+id/btnGo"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:weightSum="4"
>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Back"
android:id="#+id/btnBack"
/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Forward"
android:id="#+id/btnForward"
/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Clear"
android:id="#+id/btnClear"
/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Reload"
android:id="#+id/btnReload"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="11"
>
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/wb"
/>
</LinearLayout>
</LinearLayout>
Here is my java code.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
EditText etUrl;
Button btnGo, btnBack, btnForward, btnClear, btnReload;
WebView wb;
String url;
View v;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wb = (WebView) findViewById(R.id.wb);
wb.getSettings().setJavaScriptEnabled(true);
wb.getSettings().setUseWideViewPort(true);
wb.getSettings().setLoadWithOverviewMode(true);
wb.setWebViewClient(new ourClient());
etUrl = (EditText) findViewById(R.id.etUrl);
btnGo = (Button) findViewById(R.id.btnGo);
btnBack = (Button) findViewById(R.id.btnBack);
btnForward = (Button) findViewById(R.id.btnForward);
btnClear = (Button) findViewById(R.id.btnClear);
btnReload = (Button) findViewById(R.id.btnReload);
btnGo.setOnClickListener(this);
btnReload.setOnClickListener(this);
btnBack.setOnClickListener(this);
btnForward.setOnClickListener(this);
btnClear.setOnClickListener(this);
etUrl.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (keyEvent.getAction()==KeyEvent.ACTION_DOWN && i==KeyEvent.KEYCODE_ENTER) {
return true;
}
load();
return false;
}
});
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnGo:
load();
break;
case R.id.btnBack:
if (wb.canGoBack())
wb.goBack();
break;
case R.id.btnForward:
if (wb.canGoForward())
wb.goForward();
break;
case R.id.btnReload:
wb.reload();
break;
case R.id.btnClear:
wb.clearHistory();
break;
}
}
public void load(){
url = etUrl.getText().toString();
if (!url.startsWith("http://")) {
url = "http://" + url;
}
try {
wb.loadUrl(url);
wb.requestFocus();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), " " + e, Toast.LENGTH_LONG).show();
}
}
}
use this method to hide the keyboard:
public static void hideSoftKeyboard(Activity context) {
InputMethodManager inputManager = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputManager != null)
inputManager.hideSoftInputFromWindow(context.getWindow()
.getDecorView().getApplicationWindowToken(), 0);
context.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
call it in your load() method like:
hideSoftKeyboard(MainActivity.this);
For your second question you need to call your method inside the condition like:
etUrl.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if ((keyEvent.getAction()==KeyEvent.ACTION_DOWN) && (i==KeyEvent.KEYCODE_ENTER)){
load(); //add it here
return true;
}
return false;
}
});
EDIT
For the webview go back feature: override onKeyDown in your activity and check condition like:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && wb.canGoBack()) {
wb.goBack();
//show your back button here
return true;
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
//show other buttons
return super.onKeyDown(keyCode, event);
}
You can add the check in your onResume() and load() also and show your button accordingly..
#Override
protected void onResume() {
super.onResume();
if(wb.canGoBack()){
//show back button}
else{
//other button
}
}
Related
I have a simple app that is based on WebView.loadUrl("http://www.example.com").
When a user clicks on a URL, the default behavior is to immediately show a blank page, wait until the page is loaded, and then show this page.
I managed to show a splash screen in lieu of the blank page. However, is it possible to keep the current page rendered instead, and render the next page only when it is fully loaded?
This is, I feel, a hacky solution. I offer it as a temporary fix until someone posts the "real" way to do this.
MainActivity class:
public class MainActivity extends Activity
{
WebView webView1, webView2;
EditText editText;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText = (EditText) findViewById(R.id.edit_url);
webView1 = (WebView) findViewById(R.id.webView_1);
webView2 = (WebView) findViewById(R.id.webView_2);
webView1.setWebViewClient(client);
webView2.setWebViewClient(client);
webView1.loadUrl(editText.getText().toString());
}
private WebViewClient client = new WebViewClient()
{
public void onPageFinished(WebView webView, String url)
{
if (webView == webView1)
webView2.setVisibility(View.GONE);
else
webView1.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
Toast.makeText(MainActivity.this, "WebView " + (webView == webView1 ? "One" : "Two") + " is showing", 0).show();
}
};
private void loadUrl(String url)
{
if (webView1.getVisibility() == View.GONE)
webView1.loadUrl(url);
else
webView2.loadUrl(url);
}
public void onClick(View v)
{
loadUrl(editText.getText().toString());
}
}
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.webkit.WebView android:id="#+id/webView_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<android.webkit.WebView android:id="#+id/webView_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText android:id="#+id/edit_url"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:layout_gravity="center_vertical"
android:text="http://www.example.com" />
<Button android:id="#+id/button_load"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Load" />
</LinearLayout>
</LinearLayout>
I've been developing a simple android application.
It worked fine on several virtual devices and on HTC One S, but when I started it on Samsung Galaxy Tab 2 with Android 4.0.4 all the elements on the layout was duplicated. Its visible with the virtual keyboard and without it.
Here is the Layout file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/password_label"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:id="#+id/password_view" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ok_label"
android:id="#+id/password_confirm"
android:layout_gravity="center_horizontal"
android:onClick="checkPassword" />
</LinearLayout>
And the Activity source code:
public class PasswordActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_password);
Button button = (Button) findViewById(R.id.password_confirm);
if (SharedPreferencesHandler.isPreferenceSet(this, SharedPreferencesHandler.PreferenceKey.PASSWORD_PREFERENCE_KEY)) {
button.setText(R.string.ok_label);
} else {
button.setText(R.string.save_label);
}
EditText editText = (EditText) findViewById(R.id.password_view);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
checkPassword();
handled = true;
}
return handled;
}
});
}
//some utility methods
}
Here is a screenshot of that bug:
I'm trying to to open activity within my activity. User clicks button on the left side of the layout and the intent is shown on the right side. How this could be done while keeping the leftside buttons visible? Everytime I tried to start intent, it is opened on top of my layout covering it.
So the logic is same as tarketing HTML link to certain frame, but on android with activities/intents.
Mockup:
http://i.stack.imgur.com/jHqKd.jpg
Update:
I'd like to make this question more specific. If I open intent from my fragment it opens on fullscreen instead of filling only the are of current fragment:
Button button = (Button) view.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String url = "http://www.google.com";
Intent google = new Intent(Intent.ACTION_VIEW);
google.setData(Uri.parse(url));
getActivity().startActivity(google);
}
});
How to open intent from a fragment, so it fills only fragment, not the whole screen?
What you are looking for is fragments. Fragments can easily be added and detached from activity as you wish. So what you basically need to do is add a fragment on a button click, when the other button is clicked you should remove this fragment and add another.
Try dis code use a WebView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<Button
android:id="#+id/frst_btn"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
android:text="FIRST"/>
<Button
android:id="#+id/second_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="0"
android:text="SECOND"/>
</LinearLayout>
<WebView
android:id="#+id/webview"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
</LinearLayout>
Use this code also
Button button = (Button) findViewById (R.id.run);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String url = "URL";
WebSettings settings = webView.getSettings();
settings.setBuiltInZoomControls(true);
webView.setWebViewClient(new Callback());
webView.loadUrl(url);
}
});
private class Callback extends WebViewClient{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return (false);
}
}
Background
I have a form-like activity, which has some views that can be created dynamically upon pressing.
I'm using an xml for each field that is inflated upon clicking on a button.
What I need is that upon choosing to add a new item, it will get focus, scroll if needed, and show the keyboard so that the user can type things into it. The keyboard may be shown upon adding the field or when clicking on the EditText.
The problem
For some reason, on some devices (and I don't think it's even an android version issue) when inflating the new view, the editText within it can get focus but it doesn't show the keyboard, even if it has focus and the user clicks on it.
In such a case, the only way to show the keyboard is to click on another EditText.
I've tested it, and noticed that it doesn't occur when I don't use xml at all, meaning when i create the views only in code.
The question
Why does it occur? What can I do in order to fix it?
I've already tried so many possible solutions, but none work on all devices.
Sample Code
the next code has the described issue on xperia j (android 4.0.4) an galaxy mini (android 2.3.6) .
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ViewGroup container = (ViewGroup) findViewById(R.id.LinearLayout1);
final LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
findViewById(R.id.button).setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
final View view = inflater.inflate(R.layout.field, null);
// using the next code works when using it instead of inflating a layout:
// final EditText editText = new EditText(MainActivity.this);
// editText.setText("item " + container.getChildCount());
container.addView(view);
}
});
}
the field layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFffffff"
android:gravity="center_vertical" >
<Spinner
android:id="#+id/typeSpinner"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_centerVertical="true"
android:background="#null"
android:padding="5dp" />
<include
android:id="#+id/removeItemView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
layout="#layout/remove_item_view" />
<EditText
android:id="#+id/fieldEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/removeItemView"
android:layout_toRightOf="#+id/typeSpinner"
android:ems="10"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="field"
android:imeOptions="actionDone"
android:inputType="phone"
android:minWidth="200dp"
android:padding="5dp"
android:singleLine="true"
tools:ignore="HardcodedText" >
<requestFocus />
</EditText>
</RelativeLayout>
the main layout file:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click"
tools:ignore="HardcodedText" />
</LinearLayout>
</ScrollView>
EDIT: found a partial solution which won't show the keyboard right away, but at least it will be shown when pressing the editText:
public static void forceFocusOnView(final View view) {
if (view == null)
return;
view.post(new Runnable() {
#Override
public void run() {
view.clearFocus();
view.post(new Runnable() {
#Override
public void run() {
view.requestFocus();
}
});
}
});
}
I'm not sure in a reason of that problem. Could be some missmatches when Android sdk were rewritten in order to match some devices.
So I think that the best solution to you is to show your keyboard manually and do not try to move a train, just take the path of the least resistance:
EditText et=(EditText)this.findViewById(R.id.edit_text);
et.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(et, 0);<----------------
}
});
Here you go , man. Wish you luck.
Oh i see...
private EditText et;
private Runnable setFocus;
......
protected void onCreate(...){
.
.
.
setFocus=new Runnable(){
#Override
public void run() {
et.requestFocus();
}
};
}
....
findViewById(R.id.button).setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
final View view = inflater.inflate(R.layout.field, null);
//try this:
et=(EditText)view.findViewById(r.id.fieldEditText);
et.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(et, 0);<----------------
}
});
container.addView(view);
container.requestLayout();<--------------
et.postDelayed(setFocus,300);
}
});
I'm working on an Android app and I've got 2 editviews and a label. The user can enter 2 values and the label shows some calculation using input from the editviews. What I want is the following;
user enters either value with soft-keyboard
user presses "Return" softkey
editview should lose focus
the soft-keyboard should disappear
textview label should be recalculated
Now, the v.clearFocus only seems to works when there is another widget that can can get focus(?), so I've also added a dummie zero-pixel layout that can 'steal' the focus from the first editview. The Return key works now, but when the user switches focus from edit1 to edit2 by simply tapping then HideKeyboard() crashes. I've tried checking if inputMethodManager==null but that didn't help.
This all feels like I'm hacking to trick Android into doing some common UI behaviour, so I can't help but think that I'm overlooking something here.
Any help would be greatly appreciated. Btw I know this is similar to this question: How to lose the focus of a edittext when "done" button in the soft keyboard is pressed?
But I've tried that and it doesn't work.
So my layout xml is this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- Dummy control item so that first textview can lose focus -->
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
<EditText
android:id="#+id/editTest1"
android:layout_width="250px"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:imeOptions="actionDone" >
</EditText>
<EditText
android:id="#+id/editTest2"
android:layout_width="250px"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:imeOptions="actionDone" >
</EditText>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test123" />
</LinearLayout>
And the source is this:
public class CalcActivity extends Activity implements OnFocusChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab2_weight);
EditText testedit = (EditText) findViewById(R.id.editTest1);
testedit.setOnFocusChangeListener(this);
testedit.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId==EditorInfo.IME_ACTION_DONE){
//Clear focus here from edittext
Log.d("test app", "v.clearFocus only works when there are other controls that can get focus(?)");
v.clearFocus();
}
return false;
}
});
}
public void hideSoftKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
}
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus == false) {
Log.d("unitconverter", "onFocusChange hasFocus == false");
// update textview label
TextView bla = (TextView) findViewById(R.id.textView1);
bla.setText(String.format("%s + %s", (((EditText) findViewById(R.id.editTest1)).getText()), (((EditText) findViewById(R.id.editTest2)).getText())));
// hide keyboard
hideSoftKeyboard();
}
}
}