2014-04-21 7 views
6

मुझे एक अजीब समस्या है। मैं एक छवि स्केल करता हूं और स्केलिंग सही ढंग से काम करता है, लेकिन छवि हमेशा क्लिप हो जाती है। मैंने विभिन्न पैमाने के प्रकारों की कोशिश की - चीजें बदलीं लेकिन मैं इसे कभी भी काम नहीं कर सका।स्केलिंग के बाद मेरी छवि क्यों फिसल गई है?

बस स्पष्ट होना, यहाँ है कि मैं क्या हल करने के लिए की जरूरत है: 1. मैं ImageView के चारों ओर एक HorizontalScrollView और HorizontalView के चारों ओर एक ScrollView है। 2. मैं स्क्रॉल दृश्यों के scrollTo का उपयोग करके स्क्रॉल करता हूं) और, किसी निश्चित ईवेंट पर, ज़ूम इन करें। 3. मैं जो करना चाहता हूं वह ImageView के लिए मेरी वर्तमान स्क्रॉल स्थिति के आसपास स्केल करने के लिए है।

यहाँ लेआउट है:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ScrollView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scrollbars="none" 
     android:overScrollMode="never"> 

     <HorizontalScrollView 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:scrollbars="none" 
      android:overScrollMode="never"> 

      <ImageView 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_margin="3dp" 
       android:scaleType="fitCenter" /> 
     </HorizontalScrollView> 
    </ScrollView> 
</FrameLayout> 

स्केलिंग कोड है और यहाँ (originalWidth/originalHeight1 के पैमाने पर गणना कर रहे हैं; ImageView को targetView अंक):

public synchronized void changeScale(float newScaleFactor) { 
    this.scaleFactor = Math.max(min_zoom, Math.min(newScaleFactor, max_zoom)); 
    if (targetView != null && originalWidth > 0) { 
     int newWidth = (int)(originalWidth * scaleFactor); 
     int newHeight = (int)(originalHeight * scaleFactor); 
     onScaleChanged(targetView, scaleFactor, newWidth, newHeight); 
    } 
} 


public void onScaleChanged(View targetView, float scaleFactor, int newWidth, int newHeight) { 
    ViewGroup.LayoutParams layoutParams = targetView.getLayoutParams(); 
    layoutParams.width = newWidth; 
    layoutParams.height = newHeight; 

    // This is needed to increase the pane size (rather than zoom within the initial layout) 
    targetView.setLayoutParams(layoutParams); 
    // Tell the system to recalculate the layout 
    targetView.requestLayout(); 

    // This is needed to specify the center of scaling 
    HorizontalScrollView horizontalScrollView = (HorizontalScrollView)targetView.getParent(); 
    ScrollView vertScrollView = (ScrollView)horizontalScrollView.getParent(); 
    // ~~~ the pivot points are probably wrong 
    targetView.setPivotX(horizontalScrollView.getScrollX() * scaleFactor); 
    targetView.setPivotY(vertScrollView.getScrollY() * scaleFactor); 

    // This is needed for actual zooming 
    targetView.setScaleX(scaleFactor); 
    targetView.setScaleY(scaleFactor); 
}; 


public void zoomIn(float scaleDelta) { 
    changeScale(scaleFactor + scaleDelta); 
} 

public void zoomOut(float scaleDelta) { 
    changeScale(scaleFactor - scaleDelta); 
} 

प्रश्न 1: कैसे कर मैं क्लिपिंग रोकता हूँ? मुझे scaleType और लेआउट आकार बदलने का सही संयोजन नहीं मिल रहा है।

प्रश्न 2: जब मैं setScaleX/setScaleY का उपयोग करता हूं, तो मेरे पिवट को नए पैमाने पर कारक लगाने के बाद गणना की जानी चाहिए या क्या प्रस्तुतकर्ता स्वचालित रूप से इसका ख्याल रखता है?

+0

मुझे लगता है कि आपको यह सत्यापित करना चाहिए कि आपके छवि आकार के लिए जो मूल्य आप सेट कर रहे हैं वह स्क्रीन की सीमाओं के भीतर हैं। मुझे कल्पना है कि एक ठीक से सेट है लेकिन दूसरा एक बहती है। –

+0

मेरी छवि एक स्क्रॉलव्यू के भीतर है। यह मेरी इच्छा के किसी भी आकार का हो सकता है।जिस क्लिपिंग के बारे में मैं शिकायत करता हूं वह स्क्रॉलव्यू सीमित है जहां मैं – Yevgeniy

+0

स्क्रॉल करता हूं, आगे विस्तार करने के लिए, मेरी समस्या लगभग http://stackoverflow.com/questions/4963866/how-to-change-size-of-android-scrollview के समान है। केवल अंतर यह है कि मैं स्क्रॉलव्यू के बच्चे को स्केल करता हूं जबकि वह लड़का पूरी तरह से बच्चे को बदलता है। – Yevgeniy

उत्तर

1

स्केल को अपडेट करने के बाद आपको अमान्य(), और requestLayout() दृश्यों को अपडेट करने की आवश्यकता है।

targetView.invalidate(); 
targetView.requestLayout(); 

मैं आमतौर पर छवियों के लिए अलग-अलग पैमाने की गणना करता हूं। आप MATRIX स्केल प्रकार का उपयोग करके छवि दृश्य को स्केल करने का प्रयास कर सकते हैं। आपको अपने बाध्य डीपीआई के आकार को जानने की आवश्यकता होगी।

// Get the scaled DPI 
int boundBoxInDp = getResources().getDisplayMetrics().densityDpi * scaleFactor 

// Determine how much to scale: the dimension requiring less scaling is 
// closer to its side. This way the image always stays inside your 
// bound AND either x/y axis touches the bound but neither will go over. 
float xScale = ((float) boundBoxInDp)/newWidth; 
float yScale = ((float) boundBoxInDp)/newHeight; 
float scale = (xScale <= yScale) ? xScale : yScale; 

// scale using our calculated scale 
targetView.setScaleX(scale); 
targetView.setScaleY(scale); 

पिवोट के बारे में आपके दूसरे प्रश्न के अनुसार। शायद इसे दृश्यमान स्क्रॉल क्षेत्र के केंद्र में सेट करने की आवश्यकता होगी। स्क्रॉल करने योग्य क्षेत्र में वृद्धि होनी चाहिए जब आप छवि आकार बदलते हैं क्योंकि आप FIT_CENTER का उपयोग कर रहे हैं;

+0

दुर्भाग्य से काम नहीं किया – Yevgeniy

0

this article देखें जो कोड अच्छी तरह से काम करता है। मैंने अपने क्षैतिज स्क्रॉलव्यू और स्क्रॉलव्यू को हटा दिया और इस फ्रेम और ज़ूम लिस्टनर को मेरे फ्रेमलेआउट में संलग्न किया और तब से यह सभी बारिश और यूनिकॉर्न्स था।

मैंने आपके जैसा ही काम करने की कोशिश की, लेकिन सफलता के बिना। ऐसा लगता है कि आप HorizontalScrollView और ScrollView का उपयोग किए बिना एक ImageView स्क्रॉल कर सकते हैं। मैं अभी भी अस्पष्ट हूं कि यह क्या होता है, लेकिन मैं छवि मैट्रिक्स के उपयोग की ओर झुक रहा हूं (जैसा कि, ImageView पर setImageMatrix) या संभवतः मार्जिनलाउट पैराम का उपयोग। एंड्रॉइड पर उपलब्ध गैलरी से गैलरी स्रोत कोड को देखते हुए, मुझे मैट्रिक्स का भारी उपयोग दिखाई दे रहा है। दुर्भाग्यवश, इस पर प्रलेखन मेरे अनुमान में काफी हल्का प्रतीत होता है।

अन्य लोगों ने इसे समझ लिया है, इसलिए PanAndZoomListener में प्लग करें और आप कर चुके हैं। वही मैंने किया।

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