用特定颜色填充可绘制对象的透明部分

时间:2018-10-29 06:09:20

标签: android xml android-imagebutton

我有此透明图像,我想在透明部分内部填充特定的颜色。

image

我已经能够用我想要的特定颜色填充该图像,但是问题是该颜色还在填充ImageButton的外部。

以下是示例:

image

如何去除可绘制对象之外的多余红色?

这是我当前的 xml:

<ImageButton
    android:id="@+id/button_scan"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginRight="4dp"
    android:layout_weight="0.25"
    android:src="@drawable/ic_scan"
    android:background="@color/aub_red"
    android:backgroundTintMode="screen"
    android:textColor="@color/edittext_text" />

2 个答案:

答案 0 :(得分:0)

尝试通过添加论文进行构建

android:adjustViewBounds="true"
android:scaleType="fitXY"

如果您的图像比例受上述更改的影响,可以使用

android:scaleType="fitCenter"

答案 1 :(得分:0)

看起来父级是带有一些“ weightsum”的LinearLayout,这就是为什么ImageButton的宽度不确定的原因。

您可以创建一个框架布局,其中包含此imagebutton和imagebutton下方的另一个布局(宽度和高度与imagebutton相同)。像这样:

#pragma once

#include <vector>
#include <map>
#include <sstream>
#include <exception>
#include <iostream>
#include <numeric>
#include <algorithm>

const unsigned int EVEN = 0;
const unsigned int ODD = 1;

template<typename const std::size_t ... Dims> class DimensionPack;
template<typename ClassType, const std::size_t buffer>   class MatrixBuffer;
template<typename ClassType, const std::size_t ... Dims> class MatrixCell;
template<typename ClassType, const std::size_t ... Dims> class MatrixReference;
template<typename ClassType, const std::size_t ... Dims> class MatrixStorage;
template<typename ClassType, const std::size_t ... Dims> class MatrixAllocation;
template<typename ClassType, const std::size_t ... Dims> class MatrixLog;
template<typename ClassType, const std::size_t ... Dims> class MatrixFile;

template<typename ClassType, const std::size_t ... Dims>
class Matrix {
private:
    DimensionPack<Dims...> dp_;
    MatrixStorage<ClassType, Dims...> storage_;
    MatrixReference<ClassType, Dims...> reference_;
    MatrixAllocation<ClassType, Dims...> allocation_;

    const unsigned int numDimensions_ = dp_.total_dimensions;
    const unsigned int numElements_ = dp_.total_elements;
    std::vector<std::size_t> dimensions_ = dp.dimensions;
    std::vector<std::size_t> even_or_odd_ = dp_.even_or_odd;

public:
    Matrix() {}

    std::vector<unsigned int>& getDimensions() { return dimensions_; }
    std::vector<unsigned int>& getEvenOrOdd() { return even_or_odd_; }
    const std::size_t getNumberOfDimensions() const { return numDimensions_; }

    // Amount of fields must be equal to total matrix elements
    // Example: a 2x2 Matrix has 4 elements and a 3x3x3 has 27 
}; // Matrix

// DimensionPack & Helper Struct
struct MatrixDimensionOddOrEven {
    const std::size_t even_or_odd;
    explicit MatrixDimensionOddOrEven( unsigned int odd_or_even ) : even_or_odd( test( odd_or_even ) ) {}
private:
    const unsigned int test( unsigned int value ) const {
        if( value == 0 ) {
            std::ostringstream stream;
            stream << __FUNCTION__ << " invalid number: " << value << " must be >= 1\n";
            throw std::runtime_error( stream.str() );
        }
        return (((value % 2) == 0) ? EVEN : ODD);
    }

}; // typedef MatrixDimensionOddOrEven MatDimOddEven; 

template<const std::size_t ... Dims>
class DimensionPack {
public:
    std::vector<std::size_t> dimensions;
    std::vector<std::size_t> even_or_odd;
    const std::size_t total_dimensions = sizeof...(Dims);
    const std::size_t total_elements = countElements();

public:
    DimensionPack() : dimensions{ Dims... },
        even_or_odd{ MatrixDimensionOddOrEven{Dims}.even_or_odd... } {
    }

private:
    std::size_t countElements() {
        std::size_t val = 1; // Don't Init to 0 otherwise multiplication won't work here!
        for( std::size_t n = 0; n < dimensions.size(); n++ ) {
            val *= dimensions[n];
        }
        return val;
    }
}; // DimensionPack

template<std::size_t>
struct const_size_t {
    using type = std::size_t;
};

template<typename ClassType, const std::size_t... DimCoords>
class MatrixCell {
    std::vector<std::size_t> coordinateIndices_;
    ClassType data_;

public:
    MatrixCell() : coordinateIndices_{ DimCoords... }, data_( 0 ) {}

    // template<typename const_size_t<Dims>::type... Args>
    void addItem( ClassType item, typename const_size_t<DimCoords>::type... coords ) {
        if( !(checkItem( coords... )) ) {
            std::ostringstream stream;
            stream << __FUNCTION__ << " Current index doesn't exist\n";
            throw std::runtime_error( stream.str() );
        } else {
            if( data_ != 0 ) {
                std::ostringstream stream;
                stream << __FUNCTION__ << " Item with a value of " << data_ << " already exists at this location\n";
                std::cerr << stream;
            } else {
                data_ = item;
            }
        }
    }

    // template<typename const_size<Dims>::type... Args>
    bool checkIndex( typename const_size_t<DimCoords>::type... coords ) {
        std::vector<std::size_t> vals{ coords... };
        static bool isValid = true;
        for( unsigned u = 0; u < coordinateIndices_.size(); u++ ) {
            if( vals[u] > coordinateIndices_[u] ) {
                isValid = false;
            }
        }
        return isValid;
    }
}; // MatrixCell

// Empty Abstract Base Class
template<typename ClassType = void>
class MatrixBase {
protected:
    MatrixBase() = default;
    virtual ~MatrixBase() = default;
}; // MatrixBase

// Used For Extremely Large Data Sets
template<typename ClassType, const std::size_t bufferSize>
class MatrixBuffer {
public:
    typedef std::vector<std::size_t> dimensions;
    typedef std::vector<std::vector<ClassType>> elements;

    std::map<dimensions, elements> matrixBuffer = std::map<dimensions, elements>().reserve( bufferSize );

}; // MatrixBuffer


// Stores all of the contents of the Matrix
template<typename ClassType, const std::size_t ... Dims>
class MartrixStorage : public MatrixBase<ClassType>, DimensionPack<Dims...> {

}; // MatrixStorage

// Used to reference the storage class of the Matrix
template<typename ClassType, const std::size_t ... Dims>
class MatrixReference : public MatrixBase<ClassType>, DimensionPack<Dims...> {

};

// Used only when the user wants to create a matrix in dynamic memory.
// It handles if a user wants to use shared_ptr or unique_ptr for its contained elements (... incomplete declaration)
template<typename ClassType, const std::size_t ... Dims>
class MatrixAllocation : public MatrixBase<ClassType>, DimensionPack<Dims...> {

};

// Used to log the matrix to the console or print it via some window or to a file
template<typename ClassType, const std::size_t ... Dims>
class MatrixLog : public MatrixBase<ClassType>, DimensionPack<Dims...> {

};

// Used to create the layout for a file structure both in writing to and reading from used in conjuction with MatrixLog
template<typename ClassType, const std::size_t ... Dims>
class MatrixFile : public MatrixBase<ClassType>, DimensionPack<Dims...> {

};