滚动时Android自定义视图的填充

时间:2016-05-19 12:03:02

标签: android view padding

我写了一个自// part of the header: private: const int IMAGE_HEIGHT = 800; const float OFFSET_SCALE = 0.05f; cv::Mat Normalizer::normalize(cv::Mat source, std::vector<cv::Rect> &rectAreas, std::vector<cv::Vec3i> &eyes, std::vector<cv::Point> &chin) { /* rectAreas: 0: faceRect 1: mouth 2: brow left 3: brow right 4: nose */ // complete face cv::Rect faceArea = rectAreas[0]; int offsetX = cvRound(OFFSET_SCALE * faceArea.width); // offset x of rect to be copied to the left (to get a small area around the face) int offsetY = cvRound(OFFSET_SCALE * faceArea.height); // offset y of rect to be copied to the top (...) int x = faceArea.x - offsetX; // for calculating if rect for copying is fully inside source, fill with black pixels otherwise int y = faceArea.y - offsetY; // ... int width = faceArea.width + 2 * offsetX; // width of rect to be copied int height = faceArea.height + 2 * offsetY; // height of rect to be copied cv::Rect offsetRect(x, y, width, height); // create rect that will be copied from source // check if source = bounding rect // if true: black border int deltaX = 0, deltaY = 0; if (x < 0) // if offsetRect is not fully in source, get difference, that will be filled with black pixels { offsetRect.x = 0; // if black pixels are needed, adjust offsetRect to not start at negative coordinates deltaX = std::abs(x); // deltaX black pixels on x axis } if (y < 0) { offsetRect.y = 0; deltaY = std::abs(y); // deltaY black pixels on y axis } cv::Mat output; cv::Mat temp = cv::Mat::zeros(height + deltaY, width + deltaX, source.type()); // same size as offsetRect, starting position at deltaX:deltaY in output cv::Rect targetRect(deltaX, deltaY, offsetRect.width, offsetRect.height); source(offsetRect).copyTo(temp(targetRect)); // resize to X * IMAGE_HEIGHT (= 800) float aspectRatio = (float)temp.size().height / (float)temp.size().width; int scaledWidth = cvRound(IMAGE_HEIGHT / aspectRatio); cv::resize(temp, output, cv::Size(scaledWidth, IMAGE_HEIGHT), 0, 0, cv::INTER_CUBIC); temp.release(); temp = NULL; // adjust eye centers /* offsetRect edge - delta output edge offsetRect edge - delta output edge ----------------------- = ------------- ######### ----------------------- = ------------- old coord - margin new coord old radius new radius */ for (int i = 0; i < 2; ++i) { eyes[i][0] = cvRound((scaledWidth * (eyes[i][0] - offsetRect.x)) / (float)(offsetRect.width - deltaX)); eyes[i][1] = cvRound((IMAGE_HEIGHT * (eyes[i][1] - offsetRect.y)) / (float)(offsetRect.height - deltaY)); eyes[i][2] = cvRound((scaledWidth * eyes[i][2]) / (float)(offsetRect.width - deltaX)); //std::cout << i << ": " << eyes[i][0] << ":" << eyes[i][1] << " " << eyes[i][2] << std::endl; } // adjust rect areas rectAreas[0].x = deltaX; rectAreas[0].y = deltaY; rectAreas[0].width = output.size().width - deltaX; rectAreas[0].height = output.size().height - deltaY; /* offsetRect edge - delta output edge ----------------------- = ------------- old edge new egde */ for (int i = 1; i <= 4; ++i) { rectAreas[i].x = cvRound((scaledWidth * (rectAreas[i].x - offsetRect.x)) / (float)(offsetRect.width - deltaX)); rectAreas[i].y = cvRound((IMAGE_HEIGHT * (rectAreas[i].y - offsetRect.y)) / (float)(offsetRect.height - deltaY)); rectAreas[i].width = cvRound((scaledWidth * rectAreas[i].width) / (float)(offsetRect.width - deltaX)); rectAreas[i].height = cvRound((IMAGE_HEIGHT * rectAreas[i].height) / (float)(offsetRect.height - deltaY)); } // adjust chin points for (int i = 0; i < chin.size(); i++) { chin[i].x = cvRound((scaledWidth * (chin[i].x - offsetRect.x)) / (float)(offsetRect.width - deltaX)); chin[i].y = cvRound((IMAGE_HEIGHT * (chin[i].y - offsetRect.y)) / (float)(offsetRect.height - deltaY)); } return output; } 扩展的自定义文本视图(实际上是什么类型的视图无关紧要)。我在XML文档中向此视图添加了填充并读取这些填充并将其传递给View以应用这些填充。在我的superonDraw中,我也考虑了这些填充,一切正常。

EXCEPT ,如果我通过方法onMeasure滚动此视图,则填充不再有效。通过说不再有效,我的意思是View.scrollTo()上绘制的内容不尊重视图的填充,如下图所示: enter image description here

enter image description here

我想知道是否有任何解决方法?(PS:不要告诉我使用canvas而不是自己制作。我这样做是因为某些原因,我想要的唯一问题解决这里只是填充的东西,而不是一些很棒的替代品,谢谢!)

编辑: 我的xml

TextView

并在我的构造函数中:

<com.example.custom.MyTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text_area"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/text_bg"
    android:padding="10dp"/>

在我的onMeasure中:

public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // by calling super, the super class will take care of the paddings
        // internal, and after this, I just have to get the paddings by
        // getPaddingTop(),getPaddingLeft(),getPeddingRight(),getPaddingBottom() etc.
        }

在我的onDraw中:

public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    ......
    setMeasuredDimension(getPaddingLeft()+contentWidth+getPaddingRight()
    ,getPaddingTop()+contentHeight+getPaddingBottom());
    //whereas the contentWidth and contentHeight is determined by the widthMeasureSpec 
    // and heightMeasureSpec and some certain logic inside the view.
    // I don't think this will cause the view's content to exceed the conten area
}

0 个答案:

没有答案