46

मेरे पास DialogFragment है जो एक पॉपअप स्क्रीन की तरह View दिखाने के लिए है। खिड़की हमेशा स्क्रीन के बीच में दिखाई देती है। DialogFragment विंडो की स्थिति सेट करने का कोई तरीका है? मैंने source code पर देखा है लेकिन अभी तक कुछ भी नहीं मिला। इस तरहएंड्रॉइड में डायलॉग फ्रैगमेंट की स्थिति

उत्तर

77

कोशिश कुछ:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    getDialog().getWindow().setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP); 
    WindowManager.LayoutParams p = getDialog().getWindow().getAttributes(); 
    p.width = ViewGroup.LayoutParams.MATCH_PARENT; 
    p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE; 
    p.x = 200; 
    ... 
    getDialog().getWindow().setAttributes(p); 
    ... 

या getDialog().getWindow() के लिए अन्य तरीकों।

सेट-सामग्री कॉल करने के बाद स्थिति सेट करना सुनिश्चित करें।

+0

धन्यवाद स्टीलइट मैंने आपके जवाब को उखाड़ फेंका। हालांकि, मेरे पास भी प्रश्न हैं।आप WindowManager क्यों बदल रहे हैं। LayoutParam पी? सेट ग्रेविटी() शीर्ष पर विंडो सेट करने के लिए चाल करता है। जब मैंने परीक्षण किया था या जब मैं setGravity के बारे में प्रलेखन पढ़ता हूं तो लेआउट पैराम्स पर कोई प्रतिकूल प्रभाव नहीं प्रतीत होता है। – flobacca

+0

सवाल "स्थिति कैसे सेट करें" था, मैंने नहीं माना कि उसका मतलब 'शीर्ष' था, इसलिए मैंने वांछित प्रभाव प्राप्त करने के लिए कई विशेषताओं को सेट करने का उदाहरण दिया। – Steelight

+0

+1 क्योंकि इससे मुझे सही दिशा दिखाई दी। आखिरकार मेरे लिए क्या काम किया: http://stackoverflow.com/a/20419231/56285 – Jonik

3

मैं इस उद्देश्य के लिए पॉपअपविंडो क्लास का उपयोग कर रहा हूं क्योंकि आप दृश्य का स्थान और आकार निर्दिष्ट कर सकते हैं।

+13

पॉपअपविंडो एक टुकड़ा नहीं है, इसलिए यह काफी सिरदर्द है। –

4

getDialog().getWindow() एक DialogFragmentgetWindow() के रूप में अशक्त वापस आ जाएगी अगर होस्टिंग गतिविधि दिखाई नहीं देता है, जो इसे आप एक टुकड़ा आधारित एप्लिकेशन लिख रहे हैं अगर नहीं है के लिए काम नहीं करेगा। जब आप getAttributes() आज़माते हैं तो आपको NullPointerException मिल जाएगा।

मैं Mobistry के उत्तर की अनुशंसा करता हूं। यदि आपके पास पहले से डायलॉग फ्रैगमेंट क्लास है, तो स्विच करना बहुत मुश्किल नहीं है। बस क्रिएटडिअलॉग विधि को उस व्यक्ति के साथ प्रतिस्थापित करें जो एक पॉपअपविंडो बनाता है और देता है। फिर आप AlertDialog.builder.setView() पर आपूर्ति को पुन: उपयोग करने में सक्षम होना चाहिए, और (PopupWindow object).showAtLocation() पर कॉल करें।

67

ठीक है, मैंने अंत में DialogFragment जैसी स्थिति प्राप्त करने से पहले, इसके साथ एक या दो घंटे तक दीवार के खिलाफ सिर टक्कर लगी।

मैं यहां Steelight's answer पर निर्माण कर रहा हूं। यह मुझे सबसे सरल, सबसे विश्वसनीय दृष्टिकोण मिला है।

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) { 
    Window window = getDialog().getWindow(); 

    // set "origin" to top left corner, so to speak 
    window.setGravity(Gravity.TOP|Gravity.LEFT); 

    // after that, setting values for x and y works "naturally" 
    WindowManager.LayoutParams params = window.getAttributes(); 
    params.x = 300; 
    params.y = 100; 
    window.setAttributes(params); 

    Log.d(TAG, String.format("Positioning DialogFragment to: x %d; y %d", params.x, params.y)); 
} 

ध्यान दें कि params.width और params.softInputMode (Steelight के जवाब में प्रयुक्त) इस के लिए अप्रासंगिक हैं।


नीचे एक और पूर्ण उदाहरण है। मुझे वास्तव में एक "बटन" या "पैरेंट" व्यू के बगल में "पुष्टि बॉक्स" डायलॉग फ्रैगमेंट को संरेखित करना था, मेरे मामले में एक छवि बटन।

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

Example ConfirmBox
उदाहरण ConfirmBox अपने "स्रोत" ImageButton ऊपर (ट्रैशकैन)

/** 
* A custom DialogFragment that is positioned above given "source" component. 
* 
* @author Jonik, https://stackoverflow.com/a/20419231/56285 
*/ 
public class ConfirmBox extends DialogFragment { 
    private View source; 

    public ConfirmBox() { 
    } 

    public ConfirmBox(View source) { 
     this.source = source;    
    } 

    public static ConfirmBox newInstance(View source) { 
     return new ConfirmBox(source); 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setStyle(STYLE_NO_FRAME, R.style.Dialog); 
    } 


    @Override 
    public void onStart() { 
     super.onStart(); 

     // Less dimmed background; see https://stackoverflow.com/q/13822842/56285 
     Window window = getDialog().getWindow(); 
     WindowManager.LayoutParams params = window.getAttributes(); 
     params.dimAmount = 0.2f; // dim only a little bit 
     window.setAttributes(params); 

     // Transparent background; see https://stackoverflow.com/q/15007272/56285 
     // (Needed to make dialog's alpha shadow look good) 
     window.setBackgroundDrawableResource(android.R.color.transparent); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     // Put your dialog layout in R.layout.view_confirm_box 
     View view = inflater.inflate(R.layout.view_confirm_box, container, false); 

     // Initialise what you need; set e.g. button texts and listeners, etc. 

     // ... 

     setDialogPosition(); 

     return view; 
    } 

    /** 
    * Try to position this dialog next to "source" view 
    */ 
    private void setDialogPosition() { 
     if (source == null) { 
      return; // Leave the dialog in default position 
     } 

     // Find out location of source component on screen 
     // see https://stackoverflow.com/a/6798093/56285 
     int[] location = new int[2]; 
     source.getLocationOnScreen(location); 
     int sourceX = location[0]; 
     int sourceY = location[1]; 

     Window window = getDialog().getWindow(); 

     // set "origin" to top left corner 
     window.setGravity(Gravity.TOP|Gravity.LEFT); 

     WindowManager.LayoutParams params = window.getAttributes(); 

     // Just an example; edit to suit your needs. 
     params.x = sourceX - dpToPx(110); // about half of confirm button size left of source view 
     params.y = sourceY - dpToPx(80); // above source view 

     window.setAttributes(params); 
    } 

    public int dpToPx(float valueInDp) { 
     DisplayMetrics metrics = getActivity().getResources().getDisplayMetrics(); 
     return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics); 
    } 
} 

यह आवश्यक के रूप में निर्माता पैरामीटर या setters जोड़कर ऊपर अधिक सामान्य-उपयोग करने के लिए काफी आसान है। (मेरी अंतिम ConfirmBox एक स्टाइल बटन (है कुछ सीमाओं आदि) जिसका पाठ और View.OnClickListener कोड में अनुकूलित किया जा सकता अंदर।)

+0

बहुत बढ़िया जवाब मैंने पाया। –

+0

दोस्तों आप चट्टान - धन्यवाद - मैं उत्सुक हूँ, ** मैं इसे टुकड़े के एक्सएमएल में क्यों सेट नहीं कर सकता? ** यह मुझे लंगड़ा आईओएस देव के रूप में क्यों समझ में नहीं आता है? धन्यवाद पुरुष! :) – Fattie

+0

ग्रेट उत्तर !! मुझे अपने परिदृश्य 'स्रोत' बटन (नीचे संवाद खंड को दिखाया जाना है) में कोई समस्या है, स्क्रीन अभिविन्यास परिवर्तन पर स्थिति परिवर्तन, इसलिए अभिविन्यास को बदलने पर संवाद खंड स्थिति की स्थिति के अनुसार स्थिति को अद्यतन नहीं कर रहा है। source'। क्या आप कृपया मुझे यह करने के बारे में कुछ संकेत दे सकते हैं। – Dory

3

आप निम्न की तरह अपने DialogFragment में onResume() विधि ओवरराइड करने के लिए की जरूरत है:

@Override 
public void onResume() { 
    final Window dialogWindow = getDialog().getWindow(); 
    WindowManager.LayoutParams lp = dialogWindow.getAttributes(); 
    lp.x = 100;  // set your X position here 
    lp.y = 200;  // set your Y position here 
    dialogWindow.setAttributes(lp); 

    super.onResume(); 
} 
संबंधित मुद्दे