2010-10-01 8 views
7

मैं this के समान कुछ करने की कोशिश कर रहा हूं लेकिन एंड्रॉइड में।कस्टम प्रोग्रेसबार विजेट

alt text

एंड्रॉयड में मैं ProgressBar विस्तार कर सकते हैं, लेकिन मैं कैसे शीर्ष पर TextViews जोड़ने के लिए की शक कर रहा हूँ। आईफोन में यह आसान था क्योंकि मैं पूर्ण पदों का उपयोग कर सकता हूं, लेकिन यहां नहीं।

कोई विचार?

संपादित करें: मैंने अंगूठे को खींचने के लिए ProgressBar के बजाय SeekBar का उपयोग करने का निर्णय लिया। मैंने नीचे टिप्पणी की। कुछ बिंदुओं पर ध्यान दें:

  • मैं हार्डकोडेड मानों का उपयोग कर रहा हूं, वास्तव में तीन लेकिन यह कम या ज्यादा हो सकता है।
  • जब अंगूठे को स्थानांतरित किया जाता है तो यह 50 तक चलता है लेकिन इसे विभिन्न विकल्पों में जाना चाहिए।
  • मैं डीपीआई के बजाय पिक्सेल का उपयोग कर रहा हूं। मुझे इसे ठीक करना चाहिए।
  • अंगूठे की चाल के दौरान मुझे एनीमेशन की कमी को हल करने की आवश्यकता है।

मेरे प्रगति अब तक:

public class SliderFrameLayout extends FrameLayout implements OnSeekBarChangeListener { 
    private SeekBar mSlider; 
    private Context mContext; 
    private int mSize = 3; 
    private TextView[] mTextViews; 
    private String[] mTexts = {"Nafta", "Gas", "Gasoil"}; 

    public SliderFrameLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     mContext = context; 
     setWillNotDraw(false); 
     mTextViews = new TextView[mSize]; 
     addSlider(); 
     addTextViews(); 
    } 

    private void addTextViews() { 
     for (int i=0 ; i < mSize ; i++) { 
      TextView tv; 
      tv = new TextView(mContext); 
      tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, 
        LayoutParams.WRAP_CONTENT)); 
      tv.setText(mTexts[i]); 
      mTextViews[i] = tv; 
      addView(tv);  
     } 
    } 

    private void addSlider() { 
     FrameLayout fl = new FrameLayout(mContext, null); 
     LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 
     fl.setLayoutParams(params); 
     fl.setPadding(30, 30, 30, 0); 


     mSlider = new SeekBar(mContext, null); 
     LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 
     //lp.setMargins(30, 30, 30, 0); 
     //mSlider.setPadding(30, 30, 30, 0); 
     mSlider.setLayoutParams(lp); 
     //mSlider.setMax(mSize-1); 
     mSlider.setThumbOffset(30); 
     //mSlider.setProgressDrawable(mContext.getResources().getDrawable(R.drawable.slider_track)); 
     //mSlider.setThumb(mContext.getResources().getDrawable(R.drawable.slider_thumb)); 
     mSlider.setOnSeekBarChangeListener(this); 
     //addView(mSlider); 

     fl.addView(mSlider); 
     addView(fl); 

    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 


     Rect rectf = new Rect(); 
     mSlider.getLocalVisibleRect(rectf); 

    Log.d("WIDTH  :",String.valueOf(rectf.width())); 
    Log.d("HEIGHT  :",String.valueOf(rectf.height())); 
    Log.d("left   :",String.valueOf(rectf.left)); 
    Log.d("right  :",String.valueOf(rectf.right)); 
    Log.d("top   :",String.valueOf(rectf.top)); 
    Log.d("bottom  :",String.valueOf(rectf.bottom)); 

     int sliderWidth = mSlider.getWidth(); 

     int padding = sliderWidth/(mSize-1); 

     for (int i=0 ; i < mSize ; i++) { 
      TextView tv = mTextViews[i]; 
      tv.setPadding(i* padding, 0, 0, 0); 
     } 
    } 

    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress, 
      boolean fromUser) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onStartTrackingTouch(SeekBar seekBar) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onStopTrackingTouch(SeekBar seekBar) { 
     Log.d("SEEK", "value: " + seekBar.getProgress()); 
     seekBar.setProgress(50); 
    } 
} 
+0

क्या आपने आईफोन में एक जैसी प्रगति की है? –

+0

@ न्यूटॉयओएस: हाँ। बहुत समय पहले :) – Macarse

उत्तर

8

आप पहले ही onDraw ओवरराइड कर रहे हैं, क्यों न केवल टेक्स्ट स्ट्रिंग को खींचें? टेक्स्टव्यू जोड़ने और पैडिंग के साथ गड़बड़ करने के ऊपरी हिस्से के माध्यम से जाने के बजाय, सही जगह पर टेक्स्ट स्ट्रिंग को भौतिक रूप से खींचने के लिए बस canvas.drawText का उपयोग करें।

आप शैली और पाठ का रंग एक Paint वस्तु का उपयोग कर निर्दिष्ट कर सकते हैं:

Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
textPaint.setColor(r.getColor(R.color.text_color)); 
textPaint.setFakeBoldText(true); 
textPaint.setSubpixelText(true); 
textPaint.setTextAlign(Align.LEFT); 

और वह पेंट वस्तु पर measureText पद्धति का उपयोग करके क्या चौड़ाई एक विशेष स्ट्रिंग जब होगा खोजने के लिए द्वारा सटीक स्थिति प्राप्त एक कैनवास पर तैयार:

textWidth = (int)textPaint.measureText(mTexts[i]); 

तो फिर तुम पाठ स्ट्रिंग के अपने सरणी पर पुनरावृति और सही जगह में प्रत्येक स्ट्रिंग आकर्षित कर सकते हैं।

@Override 
protected void onDraw(Canvas canvas) { 
    int myWidth = getMeasuredWidth()-LEFT_PADDING-RIGHT_PADDING; 
    int separation = myWidth/(mSize-1); 

    for (int i = 0; i++; i < mSize) { 
    int textWidth = (int)textPaint.measureText(mTexts[i]); 
    canvas.drawText(mTexts[i], 
        LEFT_PADDING+(i*separation)-(int)(textWidth/2), 
        TOP_PADDING, 
        textPaint); 
    } 
} 

आप शायद OnDraw के बजाय onMeasure में माप के लिए करना चाहेंगे, और आप शायद ही प्रत्येक स्ट्रिंग की चौड़ाई को मापने के लिए जब आप पाठ या रंग बदलना चाहिए, लेकिन मैं यह सब में डाल दिया है (उम्मीद है) के लिए एक जगह का पालन करना आसान बनाता है।

+0

कूल, मैं इसे टेक्स्ट के लिए उपयोग करूंगा। केवल एक चीज जो मुझे याद आ रही है वह यह है कि अंगूठे को एनिमेट करने के दौरान आईफोन में मेरे पास 'moveToPosition (int position, boolean animate)' जैसा कुछ था लेकिन एंड्रॉइड में ऐसा कुछ भी नहीं है। उस पर कोई विचार? – Macarse

+0

आप जो वर्णन कर रहे हैं उसे हासिल करने का कोई आसान तरीका नहीं है (और आपका कोड आपके ऑनस्टॉपट्रिंग टच कार्यान्वयन है अनावश्यक - सेकरबार प्रगति मूल्य पहले से ही ट्रैक किए जा रहे स्पर्श से सही ढंग से सेट किया जाएगा)। मुझे लगता है कि आप कैस में अंगूठे के स्थान को एनिमेट करना चाहते हैं ई जहां उपयोगकर्ता वर्तमान स्थिति के बाएं या दाएं क्लिक करता है? आपको ऑन टच हैंडलर को ओवरराइड करने की आवश्यकता होगी, ACTION_UP के लिए सुनो और एक लूप लागू करें जो एनीमेशन अनुकरण करने के लिए उपयुक्त अंतराल पर स्लाइडर स्थिति को बदलता है। –

0

आप this उपयोग कर सकते हैं ... सटीक नहीं आप के लिए ... क्या देख लेकिन की स्थापना की और अनुकूलित करने के लिए वास्तव में आसान ...

+0

Thorat: एंड्रॉइड में आईफोन में नहीं। – Macarse

+0

एचएचएमएमएम .... क्षमा करें – kthorat

1

बस एक कोशिश। आप अपनी कस्टम प्रगति को FrameLayout के अंदर रख सकते हैं, फिर इस लेआउट के अंदर, आपको को fill_parent चौड़ाई के रूप में जोड़ना होगा। फिर आप तीन ग्रंथों को इस तरह से संरेखित कर सकते हैं: बाएं, केंद्र और दाएं। आपके ग्रंथों को ओवरराइट नहीं करना चाहिए और आप मार्जिन का उपयोग करके अपनी स्थिति को थोड़ा समायोजित कर सकते हैं।

+0

'टेक्स्ट व्यू' की संख्या तय नहीं है। तस्वीर में 3 है, लेकिन इसमें 2, 4, 5, 6, आदि – Macarse

+0

ठीक हो सकते हैं। तो आप textviews के लिए fill_parent के बजाय wrap_content का उपयोग कर सकते हैं और मार्जिन का उपयोग करके उपलब्ध स्थान में वितरित कर सकते हैं। मुझे पता है कि यह एक आदर्श समाधान नहीं है, लेकिन अन्यथा आपको दृश्य के ड्रॉमेड को ओवरराइट करना होगा और इसे स्वयं करना होगा। – MaxFish

+0

मैं अपने उत्तर को अब तक जो कुछ भी प्राप्त कर दूंगा। – Macarse

0

आपके पास करने के लिए TextViews सेट कर सकते हैं:

android:layout_width="0dp" 
android:layout_weight="1" 

यह एंड्रॉयड ढांचे TextViews रखने की देखभाल करते हैं और मैन्युअल रूप से हर एक के गद्दी की गणना से आप बचत होगी।

+0

मैं केवल 'LinearLayout' के अंदर इसका उपयोग कर सकता हूं :( – Macarse

+0

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

+0

क्यों नहीं, अपने 'टेक्स्टव्यूआउट' में 'लिनियरआउट' को अपने 'टेक्स्ट व्यू' को शामिल करने के लिए क्यों न करें ताकि आप वज़न का उपयोग कर सकें? – jqpubliq