2012-04-18 9 views
18

मैं खोज करने के लिए निम्नलिखित कोड का उपयोग जब एक EditText में उपयोगकर्ता प्रकार:उपयोगकर्ता टाइपिंग करते समय EditText पर एकाधिक ट्रिगर्स से कैसे बचें?

EditText queryView = (EditText) findViewById(R.id.querybox); 
queryView.addTextChangedListener(new TextWatcher() { 
    @Override 
    public void afterTextChanged(Editable s) { 
    triggerSearch(s.toString()); 
    } 
    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
    } 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
    } 
}); 

बहरहाल, यह कई बार चलाता है जब उपयोगकर्ता एक शब्द लिख रहा है। ऐसा होता है कि उपयोगकर्ता "हैलो" टाइप कर रहा है, यह कोड मूल्यों के साथ 5 बार ट्रिगर करेगा ("एच", "वह", "हेल", "नरक", "हैलो")। आम तौर पर, यह ठीक होगा लेकिन ट्रिगर की गई खोज महंगी है और मैं मध्यवर्ती खोजों पर संसाधनों को बर्बाद नहीं करना चाहता हूं जो कि बहुत अच्छे उपयोग नहीं हैं। मैं जो चाहता हूं वह एक श्रोता है जो उपयोगकर्ता टाइपिंग शुरू करने के बाद केवल कुछ निश्चित सीमा को ट्रिगर करता है, या triggerSearch पर कॉल करने से पहले श्रोता में प्रतीक्षा करता है, और यदि कोई अन्य ईवेंट उस प्रतीक्षा से पहले ट्रिगर होता है, तो खुद को रद्द कर देता है।

उत्तर

45

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

private final int TRIGGER_SERACH = 1; 
// Where did 1000 come from? It's arbitrary, since I can't find average android typing speed. 
private final long SEARCH_TRIGGER_DELAY_IN_MS = 1000; 

    private Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
     if (msg.what == TRIGGER_SERACH) { 
     triggerSearch(); 
     } 
    } 
    }; 

queryView.addTextChangedListener(new TextWatcher() { 

    @Override 
    public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { 

    } 

    @Override 
    public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { 

    } 

    @Override 
    public void afterTextChanged(Editable s) { 
    handler.removeMessages(TRIGGER_SERACH); 
    handler.sendEmptyMessageDelayed(TRIGGER_SERACH, SEARCH_TRIGGER_DELAY_IN_MS); 
    }); 
+2

यह हैंडलर क्लास स्थिर होना चाहिए या लीक हो सकता है। – Choletski

+0

@Choletski कृपया विस्तार से बताएं कि लीक कैसे हो सकती हैं और स्थैतिक इसे रोक देगा? – jitenagarwal19

+0

@ jitenagarwal19 एक स्थिर हैंडलर संलग्न कक्षा – andrei

4

एक समाधान तुरंत आपके ट्रिगर किए गए खोज को निष्पादित नहीं करना होगा, लेकिन कुछ अंतराल के बाद, 100ms कहें, onTextChanged विधि को कॉल करने के बाद से पारित किया गया है। इसके अतिरिक्त प्रत्येक बार टेक्स्ट टाइप होने पर इस अंतराल को रीसेट करें।

इस प्रकार ट्रिगर किए गए खोज को टाइप नहीं किया जाता है जबकि उपयोगकर्ता टाइप कर रहा है।

3

triggerSearch पर कॉल करने से पहले श्रोता में प्रतीक्षा करने के लिए; Editable s की लंबाई का परीक्षण करें।

if(s.length() > THRESHOLD)

+0

आप एक उचित दहलीज कैसे निर्धारित करते हैं? यह भी काम नहीं करेगा यदि उपयोगकर्ता एक लंबा शब्द टाइप कर रहा है जो थ्रेसहोल्ड से अधिक अक्षरों से अधिक लंबा है। – slayton

+0

जैसा कि आपने देखा है कि उपयोगकर्ता ने यह निर्दिष्ट नहीं किया है कि वे किस खोज को ट्रिगर करते हैं। संदर्भ के बिना मैं अनुमान लगाऊंगा कि कुछ बहुत सीमित या अधिक है। क्या आपने सोचा है कि जब कोई प्रति सेकंड 10 अक्षर से कम टाइप करता है, जहां "एच", "वह", "हेल", "नरक", "हैलो" कहा जाता है क्योंकि आपका दहलीज बहुत छोटा है? दोनों उत्तर मान्य हैं, अगर आप अभी भी अपराध करते हैं और सोचते हैं कि इसे समुदाय की समीक्षा की आवश्यकता है तो कृपया मेरा जवाब ध्वजांकित करें। – Sam

+0

+1 अभी भी यह कुछ परिस्थितियों के लिए एक क्लीव्रेस्ट दृष्टिकोण है – aProgrammer

0

आप दबाया हर बटन पर खोजें प्रारंभ नहीं करना चाहते हैं, तो आप जब उपयोगकर्ता किया जाता है पता करने की जरूरत। जब उपयोगकर्ता टाइपिंग करता है तो पता लगाने के प्रयास के जटिल विचारों से बचें। इससे उपयोगकर्ता को उलझन में ले जाया जाएगा जब खोज होती है।

सरल उत्तर तब "किया गया" बटन डाल दिया जाता है और बटन पर ऑनक्लिक लिस्टनर लागू होता है और वहां आपकी खोज निष्पादित करता है।

सबसे आसान कोड: एक्सएमएल

<Button 
android:onClick="onDoneClicked" 
... the rest of your button layout 
/> 

में जावा में:

@Override 
public void onDoneClicked(View view){ 
EditText queryView = (EditText) findViewById(R.id.querybox); 
triggerSearch(queryView.toString()); 
}