2014-04-15 9 views
7

एक मधुमक्खी के छत्ते लेआउट इसएंड्रॉइड में एक मधुमक्खी एक्सएमएल लेआउट बनाना संभव है?

की तरह दिखना चाहिए रंग पित्ती सिर्फ इसलिए आप समझते हैं कि मैं नीचे तत्वों बिछाने के लिए होती है।

कौन सा Layout विजेट क्या आप उपयोग करने का सुझाव देते हैं?

मैंने GridView के साथ प्रयास किया लेकिन मैं ऐसी कोशिकाओं को नहीं बना सकता, फिर FrameLayout लेकिन हाइव स्थान सेट करते समय पिक्सेल (या डीपी) मानों से निपटना नहीं चाहता।

मैं अपने wits अंत में हूँ। मैं निष्कर्ष के करीब हूं कि ऐसा कुछ एंड्रॉइड में उच्च गुणवत्ता वाले तरीके से नहीं किया जा सकता है और गेम-जैसी पुस्तकालयों का उपयोग किए बिना। मुझे आशा है कि कोई मुझे समाधान के लिए एक अच्छा सुराग देगा।

+1

आपने वास्तव में मेरी जिज्ञासा को उत्तेजित किया और मैंने कुछ गुगल किया, यह सोचकर कि यह संभव है या नहीं। सब कुछ इंगित करता है कि नहीं, यह नहीं है (यानी, सरल माध्यमों से नहीं), और गैर-आयताकार लेआउट केवल "धोखाधड़ी" द्वारा प्राप्त किए जाते हैं, जैसे http://stackoverflow.com/a/13879492/168719 या http://stackoverflow.com/a/19583072/168719 - दूसरे शब्दों में, उन्हें केवल आयताकार दिखाई देने के लिए बनाया जाता है और पारदर्शी क्षेत्र में क्लिक करने के लिए केवल उस छाप को बनाए रखने के लिए अनदेखा किया जाता है। आपके मामले में हालांकि इसे आसन्न टाइल पर सौंपना होगा, और इसे संभालने के लिए कोड को और जटिल बना दिया जाएगा। –

+0

क्या आप पंक्तियों के माध्यम से 'ऑफसेट()' विधि का उपयोग करके, 'हेक्सागोनल' पथ 'के साथ मधुमक्खियों को चित्रित करके,' व्यू 'को उपclass करके "धोखा" कर सकते हैं, उन्हें प्रत्येक को _slightly_ अलग आरजीबी मान के साथ भरकर, फिर जांच कर सकते हैं 'onTouchEvent()' में कॉर्ड से वह मूल्य? (साथ ही, मुझे लगता है कि यह एक हनीकोम्ब आकार है, जो कि उचित है।) –

+1

मुझे लगता है कि आप यह भी निर्धारित कर सकते हैं कि सादा संख्या क्रंचिंग के माध्यम से स्पर्श किस क्षेत्र में है, लेकिन यह जितना अधिक करना चाहता है उससे ज्यादा गणित है। __ संपादित करें: __ किसी ने पहले से ही गणित किया है, और जावा में! http://www.gdreflections.com/2011/02/hexagonal-grid-math.html –

उत्तर

6

क्योंकि मैं इच्छित उद्देश्य या आवश्यकताओं के बारे में निश्चित नहीं हूं, निम्नलिखित केवल प्रमाण-अवधारणा है। HoneycombView कक्षा में कोई अवैध तर्क जांच नहीं है, या वास्तव में किसी भी प्रकार का अपवाद हैंडलिंग है। अधिकांश गुण "कठोर कोडित" होते हैं, जैसे दीवार रंग और चौड़ाई, सेल रंग और अभिविन्यास इत्यादि। इन्हें उपयुक्त सेटर्स और गेटर्स के अतिरिक्त आसानी से संशोधित किया जाता है। मैंने इसका उपयोग करने के लिए एक सरल Activity कक्षा शामिल की है।

public class HoneycombView extends View 
{ 
    private Paint wallPaint = new Paint(); 
    private Paint fillPaint = new Paint(); 
    private Paint cachePaint = new Paint(); 
    private Path combPath; 
    private Bitmap cacheBmp; 
    private Canvas cacheCan; 

    private int cellWidth; 
    private int columns; 
    private int rows; 
    private boolean[][] cellSet; 

    private OnCellClickListener listener; 

    public HoneycombView(Context context) 
    { 
     this(context, null); 
    } 

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

     wallPaint.setColor(Color.YELLOW); 
     wallPaint.setStyle(Paint.Style.STROKE); 
     wallPaint.setStrokeWidth(5f); 

     fillPaint.setStyle(Paint.Style.FILL);  
     cachePaint.setStyle(Paint.Style.FILL); 
    } 

    public void initialize(int columns, int rows) 
    { 
     this.columns = columns; 
     this.rows = rows; 

     this.cellSet = new boolean[columns][rows]; 
    } 

    public interface OnCellClickListener 
    { 
     public void onCellClick(int column, int row); 
    } 

    public void setOnCellClickListener(OnCellClickListener listener) 
    { 
     this.listener = listener; 
    } 

    public void setCell(int column, int row, boolean isSet) 
    { 
     cellSet[column][row] = isSet; 
     invalidate(); 
    } 

    public boolean isCellSet(int column, int row) 
    { 
     return cellSet[column][row]; 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) 
    { 
     super.onSizeChanged(w, h, oldw, oldh); 

     cacheBmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     cacheCan = new Canvas(cacheBmp); 

     cellWidth = 2 * w/(2 * columns + columns - 1); 
    } 

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

     canvas.drawColor(Color.WHITE); 

     boolean oddRow; 
     int xOff; 

     combPath = getHexPath(cellWidth/2f, cellWidth/2f, (float) (cellWidth * Math.sqrt(3)/4)); 

     for (int r = 0; r < rows; r++) 
     { 
      oddRow = (r & 1) == 1; 
      xOff = 0; 

      for (int c = 0; c < columns; c++) 
      { 
       if (!(oddRow && c == columns - 1)) 
       { 
        fillPaint.setColor(cellSet[c][r] ? Color.RED : Color.WHITE); 
        canvas.drawPath(combPath, fillPaint); 

        canvas.drawPath(combPath, wallPaint); 

        cachePaint.setColor(Color.argb(255, 1, c, r)); 
        cacheCan.drawPath(combPath, cachePaint); 

        combPath.offset((int) (1.5f * cellWidth), 0); 
        xOff += 1.5f * cellWidth; 
       } 
      } 

      combPath.offset(-xOff + (oddRow ? -1 : 1) * 3 * cellWidth/4, (float) (cellWidth * Math.sqrt(3)/4)); 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) 
    { 
     if (event.getAction() != MotionEvent.ACTION_DOWN) 
      return true; 

     int pixel = cacheBmp.getPixel((int) event.getX(), (int) event.getY()); 

     int r = Color.red(pixel); 
     if (r == 1) 
     { 
      int g = Color.green(pixel); 
      int b = Color.blue(pixel); 

      if (listener != null) 
      { 
       listener.onCellClick(g, b); 
      } 
     } 
     return true; 
    } 

    private Path getHexPath(float size, float centerX, float centerY) 
    { 
     Path path = new Path(); 

     for (int j = 0; j <= 6; j++) 
     { 
      double angle = j * Math.PI/3; 
      float x = (float) (centerX + size * Math.cos(angle)); 
      float y = (float) (centerY + size * Math.sin(angle)); 
      if (j == 0) 
      { 
       path.moveTo(x, y); 
      } 
      else 
      { 
       path.lineTo(x, y); 
      } 
     } 

     return path; 
    } 
} 

और Activity:

public class MainActivity extends Activity 
implements HoneycombView.OnCellClickListener 
{ 
    HoneycombView honey; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     getWindow().requestFeature(Window.FEATURE_NO_TITLE); 

     honey = new HoneycombView(this); 
     honey.initialize(4, 8); 
     honey.setOnCellClickListener(this); 

     setContentView(honey); 
    } 

    @Override 
    public void onCellClick(int column, int row) 
    { 
     honey.setCell(column, row, !honey.isCellSet(column, row)); 
    } 
} 

Sample image

मैं थोड़ा निर्धारित करने के लिए जहां स्पर्श घटनाओं घटित होता एक क्षेत्र का रंग बदलने की मेरी प्रारंभिक सुझाव के साथ चला गया है, लेकिन मैं तो में कर समाप्त हो गया एक सदस्य Bitmap इसलिए ऑन-स्क्रीन रंग अप्रभावित हैं। जैसा कि आप कोड से देख सकते हैं, इस Bitmap में सेल्स Color के आरजीबी घटकों में प्रासंगिक सेल जानकारी को एन्कोड करने के लिए इस तरह से भरे हुए हैं। रेड घटक 1 को इंगित करने के लिए सेट किया गया है कि दिया गया पिक्सेल प्रासंगिक क्षेत्र (यानी, पूरे "हनीकोम्ब" के भीतर) है। ग्रिड के भीतर सेल के कॉलम और पंक्ति की स्थिति को ग्रीन और ब्लू घटकों में एन्कोड किया जाता है, और onTouchEvent() विधि में आसानी से पुनर्प्राप्त किया जाता है।

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

मैं लगभग क्रेडिट देना भूल गया: मुझे this question से हेक्सागोनल Path कोड मिला।

+0

क्या यह स्क्रोल करने योग्य है? –

+0

जैसा नहीं है, लेकिन मुझे लगता है कि आप बिना किसी परेशानी के 'स्क्रॉल व्यू' में लपेट सकते हैं। मैंने इसका परीक्षण नहीं किया है, यद्यपि। –

+0

ठीक है। मै कोशिश करूँगा। धन्यवाद बीटीडब्ल्यू –

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