2012-02-16 16 views
14

पर कॉल करते समय एक कीबोर्ड खुला नहीं रह सकता है क्योंकि जिस तरह से आप WebView पर जावास्क्रिप्ट को कॉल करते हैं, loadUrl ("जावास्क्रिप्ट: ...") के माध्यम से होता है; कीबोर्ड खुला नहीं रह सकता है।WebView loadUrl() के दौरान सॉफ्ट कीबोर्ड छुपाता है, जिसका अर्थ है कि जावास्क्रिप्ट

loadUrl() विधि loadUrlImpl() कहता है, जो एक विधि clearHelpers() कहा जाता है जो तब clearTextEntry() कहता है, जो तब hideSoftKeyboard() कॉल और फिर हम ओह के रूप में कुंजीपटल चला जाता है इतना अकेला हो गया है कहते हैं।

जहां तक ​​मैं देख सकता हूं कि वे सभी निजी हैं और इन्हें ओवरराइड नहीं किया जा सकता है।

क्या किसी ने इसके लिए कोई समाधान पाया है? क्या कीबोर्ड को खोलने के लिए मजबूर करने या लोड यूआरएल() के माध्यम से बिना जावास्क्रिप्ट को सीधे कॉल करने का कोई तरीका है?

क्या वैसे भी वेबव्यू को ओवरराइड करने के लिए (निजी विधि) clearTextEntry() को कॉल करने से रोकने के लिए है?

+0

loadUrl() के बाद इसे कॉल करने का प्रयास करें; ((इनपुट मोड मैनेजर) getSystemService (Context.INPUT_METHOD_SERVICE))। टॉगल सॉफ़्ट इनपुट (इनपुट मोड मैनेजर .HOW_FORCED, इनपुट मोड मैनेजर। HIDE_IMPLICIT_ONLY); – zeitue

+0

हम्मम्म, बहुत करीब। कुंजीपटल बंद हो जाता है और फिर इसके साथ फिर से वास्तविक फिर से खोलता है। बहुत अजीब लग रहा है;)। हालांकि मैं इस विचार के साथ अधिक प्रयोग कर सकता हूं। – cottonBallPaws

+0

समस्या का एक और हिस्सा यह है कि clearTextEntry() उस संपादन टेक्स्ट को भी हटा देता है जिस पर कीबोर्ड केंद्रित है। – cottonBallPaws

उत्तर

12

अद्यतन

किटकैट सीधे जावास्क्रिप्ट लागू के लिए एक सार्वजनिक विधि कहा: evaluateJavascript()

पुराने API के लिए, आप नीचे दिए की तरह एक समाधान की कोशिश कर सकते हैं, लेकिन अगर मैं यह करने के लिए किया था फिर मैं देखने के लिए चाहते हैं केवल एक संगतता विधि बनाने पर कि किटकैट उपर्युक्त विधि और पुराने उपकरणों पर उपयोग करता है, एक आंतरिक निजी विधि पर ड्रिल करने के लिए प्रतिबिंब का उपयोग करता है: BrowserFrame.stringByEvaluatingJavaScriptFromString()

फिर आप बिना किसी सौदे के जावास्क्रिप्ट को कॉल कर सकते हैं adUrl और स्क्रिप्ट में "javascript: " जोड़ना।

ओल्ड उत्तर

आलोक कुलकर्णी द्वारा अनुरोध के रूप में, मैं एक संभावित समाधान, मैं इस के लिए के बारे में सोचा का एक मोटा जानकारी देंगे। मैंने वास्तव में कोशिश नहीं की है लेकिन सिद्धांत रूप में इसे काम करना चाहिए। यह कोड किसी न किसी होने वाला है और सिर्फ एक उदाहरण के रूप में काम करने के लिए है।

loadUrl() के माध्यम से कॉल भेजने के बजाय, आप अपने जावास्क्रिप्ट कॉल कतारबद्ध करते हैं और फिर जावास्क्रिप्ट उन्हें नीचे खींचते हैं। कुछ चीजें जैसे:

private final Object LOCK = new Object(); 
private StringBuilder mPendingJS; 

public void execJS(String js) { 
    synchronized(LOCK) { 
     if (mPendingJS == null) { 
      mPendingJS = new StringBuilder(); 
      mPendingJS.append("javascript: "); 
     } 
     mPendingJS 
      .append(js) 
      .append("; "); 
    } 
} 

loadUrl() को कॉल करने के बजाय उस विधि को कॉल करें। (इस सरल बनाने के लिए मैंने एक सिंक्रनाइज़ ब्लॉक का उपयोग किया, लेकिन यह एक अलग मार्ग के लिए बेहतर हो सकता है। चूंकि जावास्क्रिप्ट अपने धागे पर चलता है, इसलिए इसे थ्रेड को किसी अन्य तरीके से सुरक्षित करने की आवश्यकता होगी)।

public class JSInterface { 

    public String getPendingJS() { 
     synchronized(LOCK) { 
      String pendingCommands = mPendingJS.toString(); 
      mPendingJS.setLength(0); 
      mPendingJS.append("javascript: "); 
      return pendingCommands; 
     } 
    } 

} 

लंबित आदेशों के साथ एक स्ट्रिंग रिटर्न और उन्हें तो वे फिर से वापस आ नहीं मिलता साफ करता है कि:

फिर अपने WebView इस तरह एक अंतरफलक होगा।

आप इस तरह WebView में जोड़ने होगा:

mWebView.addJavascriptInterface(new JSInterface(), "JSInterface");

फिर अपने जावास्क्रिप्ट में आप जो में लंबित आदेशों फ्लश करने के लिए कुछ अंतराल सेट होगा। प्रत्येक अंतराल पर यह JSInterface.getPendingJS() पर कॉल करेगा जो सभी लंबित आदेशों का एक स्ट्रिंग वापस करेगा और फिर आप उन्हें निष्पादित कर सकते हैं।

आप यह देखने के लिए execJS विधि में एक चेक जोड़कर इसे और सुधार सकते हैं यह देखने के लिए कि WebView में कोई संपादन टेक्स्ट मौजूद है या नहीं। यदि कोई है, तो आप इस क्यूइंग विधि का उपयोग करेंगे, लेकिन यदि फोकस में कोई नहीं था तो आप केवल loadUrl() को सामान्य की तरह कॉल कर सकते हैं। इस तरह यह वास्तव में केवल इस कामकाज का उपयोग करता है जब इसे वास्तव में आवश्यकता होती है।

+0

स्निपेट के लिए धन्यवाद, वास्तव में आपके प्रयास की सराहना करते हैं। मैंने 2.3 पर जेएस से जावास्क्रिप्ट इंटरफेस विधि को कॉल करने और निश्चित रूप से तोड़ने की जांच की है। तो मुझे डर है कि यह 2.3 पर काम नहीं कर सकता है। लेकिन मैं अन्य 2.x प्लेटफॉर्म पर जांच करूंगा कि क्या यह काम कर रहा है या नहीं। धन्यवाद। –

+1

यह ईवेंट संचालित अनुप्रयोगों के लिए काम नहीं करेगा। चैट/एसएमएस/टेलीफोनी ऐप्स के बारे में सोचें। जब आप टाइप कर रहे हों, जावा परत को किसी ईवेंट के साथ यूआई को सूचित करने की आवश्यकता है।आप इसे हमेशा जावास्क्रिप्ट से खींच नहीं सकते हैं। – Nizzy

+0

मैंने जेएस में ** Eval (jsString) ** फ़ंक्शन का उपयोग करके अपनी विधि को लागू करने का प्रयास किया। लेकिन यह फोकस किसी भी विचार को खोने का कारण बनता है? – DroidBot

0

पुराने एपीआई (पूर्व 1 9) के संबंध में, मैंने छोड़े गए उत्तर के लिए एक समान विधि का उपयोग किया, लेकिन थोड़ा अलग।

पहले, मैं अगर कुंजीपटल मोटे तौर पर तो जैसे वेबव्यू में जावास्क्रिप्ट का उपयोग करके प्रदर्शित किया जाता है का ट्रैक रखने:

document.addEventListener("focus", function(e){   
    var el = e.target; 
    reportKeyboardDisplayedToJava(isInputElement(el)); 
}, true); 

document.addEventListener("blur", function(e){   
    reportKeyboardDisplayedToJava(false); 
}, true); 

तो कुंजीपटल प्रदर्शित किया जाता है, और एक js इंजेक्शन एंड्रॉयड जावा परत करने की कोशिश कर रहा है - मैं उस इंजेक्शन को "स्थगित" करता हूं। मैं इसे एक स्ट्रिंग सूची में जोड़ता हूं, उपयोगकर्ता को अपना इनपुट पूरा करने की अनुमति देता है, और उसके बाद कीबोर्ड गायब होने पर, मैं इसका पता लगाता हूं और इंजेक्शन के बैकलॉग निष्पादित करता हूं।

संबंधित मुद्दे