2012-12-30 21 views
6

जहां तक ​​मेरा जानकारी है, पहले जेली बीन्स के संस्करणों था निर्धारित करें और रद्द बटन जब TimePickerDialog का उपयोग कर। जेली बीन्स में केवल हो गया बटन।एंड्रॉइड जेलीबीन टाइमपिकरडियलॉग में रद्द करने का कोई तरीका है?

मैं बस छोड़ सकता बटन हो गया है, और संवाद के बाहर क्लिक करके संवाद को बंद कर सकता है, लेकिन अगर दबाने हो गया या संवाद के बाहर मेरी onTimeSetListener कहा जाता हो जाता है।

तो मुझे this stackoverflow question मिला जो वर्णन करता है कि डेटपिकरडियलॉग का उपयोग करते समय एक बग है। डेटपिकरडियलॉग का उपयोग करके समस्या को ठीक करने के लिए, मुझे प्रारंभ करने पर onDateSetListenernull पर सेट करना था, और BUTTON_POSITIVE (सेट) और BUTTON_NEGATIVE (रद्द करें) पर क्लिक करने के लिए अपने स्वयं के बटन लागू करें। कौन सा है, ठीक है, क्योंकि जब बटन सेट कहा जाता है मैं की तरह DatePicker मूल्यों का उपयोग कर सकते इस

int yearPicked = dateDlg.getDatePicker().getYear(); 
int monthPicked = dateDlg.getDatePicker().getMonth(); 
int dayPicked = dateDlg.getDatePicker().getDayOfMonth(); 

तो onDateSetListener उपयोग करने के लिए कोई जरूरत नहीं है, लेकिन अगर मैं होता, इसे फिर से जब दबाने ही कहा जाता है सेट या रद्द करें।

मैं TimePickerDialog उसी तरह उपयोग करने के लिए कोशिश की, लेकिन समस्या यह है कि BUTTON_POSITIVE onClick विधि के अंदर, मैं घंटे और मिनट मूल्यों से पहले के रूप में, timepicker रूप DatePickerDialog उपयोग नहीं कर सकते क्योंकि TimePickerDialogप्रदान नहीं करता है, हैडेटपिकर प्रदान करता है। और फिर यदि मैं onTimeSetListener का उपयोग करता, तो इसे कुछ दबाकर बुलाया जाएगा।

Calendar cal = Calendar.getInstance(); 

int hour = cal.get(Calendar.HOUR_OF_DAY); 
int min = cal.get(Calendar.MINUTE); 

final TimePickerDialog timeDlg = new TimePickerDialog(PreferencesActivity.this, null, hour, min, true); 

// Make the Set button 
timeDlg.setButton(DialogInterface.BUTTON_POSITIVE, "Set", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int which) { 
     if (which == DialogInterface.BUTTON_POSITIVE) { 
      // CANNOT ACCES THE VALUES 
      Toast.makeText(PreferencesActivity.this, "Set", Toast.LENGTH_SHORT).show(); 
     } 
    } 
}); 


// Set the Cancel button 
timeDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int which) { 
     if (which == DialogInterface.BUTTON_NEGATIVE) { 
      Toast.makeText(PreferencesActivity.this, "Cancel", Toast.LENGTH_SHORT).show(); 
     } 
    } 
}); 

timeDlg.show(); 
+0

ठीक है, फिर भी आप दर्ज किए गए मानों को कैप्चर करने के लिए 'टाइमपिकरडियलॉग.ऑनटाइमसेट लिस्टनर' पंजीकृत कर सकते हैं, लेकिन यदि नकारात्मक बटन टैप किया गया है तो बस उनके साथ कुछ भी न करें, है ना? –

+0

यह समस्या है, ऑनटाइमसेट लिस्टनर को तब कहा जाता है जब सकारात्मक, नकारात्मक और बैक बटन दबाया जाता है। – Marko

+1

मुझे एक ही समस्या थी, ध्यान दें कि नीचे स्वीकृत उत्तर पिछड़ा संगत (पूर्व जेबी) नहीं है। Sice मुझे एसडीके 8+ की आवश्यकता थी, मैंने इसे एक विस्तारित खंड संवाद के अंदर एक बूलियन के साथ हल किया, और वहां पर क्लिक किया (क्लिक करें)। – auval

उत्तर

8

अपनी टिप्पणी के आधार पर यह आसान पर्याप्त एक बूलियन मामले 'रद्द करें' क्लिक किया जाता है में चलने से अपने तर्क को रोकने के लिए साथ OnTimeSetListener कॉलबैक रक्षा करने के लिए किया जाना चाहिए।

मैं अपने कोड के साथ एक त्वरित होता था, और निम्न ठीक काम करने के लिए लग रहा था: उदाहरण के लिये

private boolean mIgnoreTimeSet = false; 

final TimePickerDialog timeDlg = new TimePickerDialog(PreferencesActivity.this, PreferencesActivity.this, hour, min, true); 

// Make the Set button 
timeDlg.setButton(DialogInterface.BUTTON_POSITIVE, "Set", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int which) { 
     mIgnoreTimeSet = false; 
     // only manually invoke OnTimeSetListener (through the dialog) on pre-ICS devices 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) timeDlg.onClick(dialog, which); 
     Toast.makeText(getApplicationContext(), "Set", Toast.LENGTH_SHORT).show(); 
    } 
}); 

// Set the Cancel button 
timeDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int which) { 
     Toast.makeText(getApplicationContext(), "Cancel", Toast.LENGTH_SHORT).show(); 
     mIgnoreTimeSet = true; 
     dialog.cancel(); 
    } 
}); 

timeDlg.show(); 

@Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 
    if (mIgnoreTimeSet) return; 
    // get the values here - this will only run if 'Set' was clicked 
} 

, मैं अपने PreferencesActivity औजार OnTimeSetListener मान लिया गया है। चूंकि onTimeSet(...)onClick(...) के बाद कॉल किया जाता है, तो आप बस एक बूलियन टॉगल कर सकते हैं जो यह निर्धारित करेगा कि आपको कॉलबैक में मानों के साथ कुछ करना चाहिए या बस उन्हें अनदेखा करना चाहिए।

मुझे यह मानना ​​है कि यह आदर्श नहीं है, लेकिन कम से कम कार्यात्मक है। छुट्टियों के बाद मैं एक 'बेहतर' समाधान में एक और नजर रखने की कोशिश करूंगा।

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


// संपादित करें: संभावित विकल्प?(परीक्षण नहीं)

दूसरा विकल्प है, जो थोड़ा 'क्लीनर' हो सकता है: विस्तार TimePickerDialog और (खाली) सार्वजनिक विधि के ऊपर लिख:

public void onTimeChanged(TimePicker view, int hourOfDay, int minute) 

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


// EDIT2: पूर्व आईसीएस उपकरणों के लिए समर्थन

के बारे में प्रस्तावित समाधान पूर्व आईसीएस उपकरणों पर काम नहीं कर रहा टिप्पणियों के एक जोड़े को प्राप्त करने के बाद, मैं उपरोक्त कोड में कुछ बदलाव करने बना - यहां तक ​​कि कठिन यह मूल प्रश्न के दायरे में नहीं था।

प्री-आईसीएस और पोस्ट-आईसीएस उपकरणों के बीच मुख्य अंतर यह है कि OnTimeSetListener कॉलबैक स्वचालित रूप से आपके संवाद बटन के onClick() विधि के बाद लागू नहीं होता है। इसके लिए एक सरल कामकाज संवाद पर onClick() विधि को कॉल करना है, जो श्रोता को कॉल करेगा। उपर्युक्त समाधान में, मैंने एक संस्करण कोड चेक जोड़ा है, क्योंकि अन्यथा आपके श्रोता को पोस्ट-आईसीएस उपकरणों पर दो बार बुलाया जा सकता है, जिससे अवांछित दुष्प्रभाव हो सकते हैं।

एंड्रॉइड 2.1-अपडेट 1 और एंड्रॉइड 4.2.2 पर परीक्षण और पुष्टि व्यवहार।

+0

आपके उत्तर के लिए धन्यवाद, कोड और खोज के साथ एक दिन खेलें। बुलियन के साथ चाल अच्छा काम करता है। मेरी PreferecesActivity OnTimeListener लागू नहीं करता है, लेकिन मुझे विचार मिला। – Marko

+0

यह 4.1 के साथ काम करता है लेकिन 2.2 –

+1

@AdilMalik के साथ काम नहीं करता है: कुछ टिप्पणियों को पढ़ने के बाद प्रस्तावित समाधान प्री-आईसीएस उपकरणों पर काम नहीं करता है, मैंने इसके लिए समायोजित करने के लिए एक छोटा सा परिवर्तन किया है। कृपया अधिक जानकारी के लिए दूसरे संपादन का संदर्भ लें। –

1

मुझे अपने नेक्सस 7 (मेरे नेक्सस वन, जिंजरब्रेड, उसी टाइमपिकरडियलॉग के लिए सेट और रद्द बटन रखने वाले) पर जेली बीन के लिए टाइमपिकरडियलॉग के साथ "डोन-बटन-केवल" समस्या का अनुभव करते समय यह धागा मिला। हालांकि, यह दिखाई देगा कि मेरे नेक्सस 7 (बिल्ड नंबर जेडब्लूआर 66 वाई) पर 4.3 जेली बीन के बाद के अपडेट के साथ उचित बटन, सेट और रद्द करें, वापस आ गए हैं।

इस समस्या का शोध करने में, हालांकि, मैं इस Stackoverflow thread में आया था, जो कि तिथिप्रिकरडियलोग के साथ बड़ी समस्याओं को उल्लिखित करता है (एक संदर्भित बग रिपोर्ट में टाइमपीकरडियलॉग के लिए संकेतित समान मुद्दों के साथ) और एक समाधान प्रदान करता है।

सावधान रहें कि इन संवादों का उपयोग सावधानी से विचार किया जाना चाहिए क्योंकि वे एंड्रॉइड के कुछ संस्करणों में सही ढंग से काम नहीं करते हैं (उपरोक्त थ्रेड में दिए गए समाधान का उपयोग "उत्पादन कोड में" नहीं किया जा रहा है, इसके लेखक के अनुसार)।

+0

यह सुनकर अच्छा लगा कि समस्या नवीनतम संस्करण के साथ तय की गई है। धन्यवाद – Marko

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