"马赛克" (分裂)图像 - Gmail的信件风格 [英] "Mosaic" (splitted) images - Gmail's letters style

查看:181
本文介绍了"马赛克" (分裂)图像 - Gmail的信件风格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Gmail中的新版本中,有一个很酷的ImageView显示多个联系人图像,它(链接的此处为例)。

On the new versions of gmail, there is a cool imageView that shows multiple contacts images in it (link here for example) .

例如,如果有人给我发了一封电子邮件,我只看到他的形象:

for example, if someone has sent me an email, i only see his image:

#######
#     #
#  A  #
#     #
#######

如果我回答他说,我可以看到我的形象在它旁边,但无论我的形象和他的减半,共享ImageView的相同的空间(我认为双方都有scaleType是居中裁剪):

if i've replied to him, i can see my image next to it, but both my image and his are halved and share the same space of the imageView (and i think both have scaleType to be center crop) :

#######
#  #  #
# A# B#
#  #  #
#######

如果其他人也加入了谈话,也可能是这样的:

if another person has joined the conversation, it could look like this:

#######
#  # B#
# A####
#  # C#
#######

如果另一个已经加入,它可能是这样的:

and if another one has joined, it could look like this:

#######
# A# C#
#######
# B# D#
#######

我不知道有关的项目顺序(和规则,所以这里的一切是我的猜测),而当越来越多的人正在加入会发生什么。

i'm not sure about the order of the items (and the rules, so everything here is my guess) , and what happens when more people are joining.

最重要的是,我想知道如何做到这一点。

the important thing is that i want to know how to achieve this .

没有人知道一个解决方案吗?他们是如何做到的?该视图用于?

does anyone know of a solution for this? how they did it? which view was used?

这是最肯定是一个自定义视图,但什么是做到这一点的最好方法是什么?一种方式,可能是最有效的,不使用大量的内存...

it's most certainly a custom view, but what's the best way to do it? a way that is probably most efficient and doesn't use a lot of memory ...

我甚至想使最终图像是圆形的,所以它可能是更好的来处理的ImageView的位图,而不是...

i might even want to make the final image to be rounded, so it might be better to handle bitmaps instead of an imageView...

我什至不知道如何调用这样的观点。我已经想到了一个CollageView或MosaicView。

i'm not even sure how to call such a view. i've thought of a "CollageView" or a "MosaicView" .

只是要清楚,我认为,这样的问题应该使用下一个API来处理:

just to make it clear, i think that such a problem should be handled using the next API :

public static Bitmap createMosaicOfBitmaps(int targetWidth,int targetHeight,ArrayList<Bitmap> imagesToShow)

或者,如果位图可能会占用过多的内存,我们可以使用类似:

or, if the bitmaps might take too much memory , we could use something like:

public static Bitmap createMosaicOfBitmaps(int targetWidth,int targetHeight,ArrayList<LazyBitmap> imagesToShow)

/**interface for lazy loading of a bitmap, while downscaling the bitmap to the needed size*/
public interface LazyBitmap{
   public getBitmap(int width,int height);
}

我已经拿出2解决方案,每个人都有自己的优点和缺点,但我仍然需要在最后的结果(特别是圆角的,但也许其他的一些东西)执行特殊效果,这一点是我不知道该怎么办。

i've come up with 2 solutions, each has its own advantages and disadvantages, but i still need to perform special effects on the final result (especially rounded corners, but maybe other things too ), and this is something that i don't know how to do.

任何人都可以请帮助?你觉得谷歌已经用在他们的应用程序?

can anyone please help? what do you think google has used on their app ?

编辑:我想出了一些可能的解决方案,对于每一个我写的答案,这个线程。我不知道这是最好的,所以我已经张贴了他们。我想每个人都有自己的优点和缺点。

i've come up with a few possible solutions, for each i've written an answer to this thread. i'm not sure which is the best so i've posted them all . i guess each has its own advantages and disadvantages.

无我目前的解决方案的处理,因为我已经提供了一个位图,但他们很直观...

none of my current solutions handles a bitmap as i've offered, but they are quite intuitive...

我还是希望有一些建议,如何这应该在你看来完成。

i would still wish for some advice as to how this should be done in your opinion.

推荐答案

这里有一个解决方案,我称之为:

here's a solution i call:

它使用XML来设置mosaicView将是什么样子。还没有,因为我已经计划了,但它可能会帮助一些人谁需要这样的东西,可以改变它,他们希望的方式。

it uses XML to set how the mosaicView would look like. still not as i've planned, but it might help some people who need such a thing and be able to change it the way they want.

我已经添加是添加自定义的分频器(使用IcsLinearLayout从actionBarSherlock本)的能力。当然,你可以添加任何你想...

what i've added is the ability to add custom dividers (uses IcsLinearLayout from actionBarSherlock for this) . of course, you can add whatever you wish...

这里的code:

public class MosaicView extends FrameLayout {

    public static final int SHOW_DIVIDER_NONE = 0;
    public static final int SHOW_DIVIDER_OUTER = 0x01;
    public static final int SHOW_DIVIDER_INNER = 0x02;

    private ImageView mTopLeftImageView, mTopRightImageView, mBottomRightImageView, mBottomLeftImageView;
    private IcsLinearLayout mLeftContainer, mRightContainer, mMainContainer;
    private int mShowDivider;
    private Drawable mHorizontalDividerDrawable;
    private Drawable mVerticalDividerDrawable;

    public MosaicView(final Context context) {
        super(context);
        init(context, null, 0);
    }

    public MosaicView(final Context context, final AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public MosaicView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(final Context context, final AttributeSet attrs, final int defStyle) {
        removeAllViews();
        final LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.mosaic_view, this, true);
        mTopLeftImageView = (ImageView) findViewById(R.id.mosaicView__topLeftImageView);
        mTopRightImageView = (ImageView) findViewById(R.id.mosaicView__topRightImageView);
        mBottomLeftImageView = (ImageView) findViewById(R.id.mosaicView__bottomLeftImageView);
        mBottomRightImageView = (ImageView) findViewById(R.id.mosaicView__bottomRightImageView);
        mLeftContainer = (IcsLinearLayout) findViewById(R.id.mosaicView__leftContainer);
        mRightContainer = (IcsLinearLayout) findViewById(R.id.mosaicView__rightContainer);
        mMainContainer = (IcsLinearLayout) findViewById(R.id.mosaicView__mainContainer);
        //
        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MosaicView, defStyle, 0);
        final int attributeCount = a.getIndexCount();
        for (int i = 0; i < attributeCount; i++) {
            final int curAttr = a.getIndex(i);
            switch (curAttr) {
            case R.styleable.MosaicView_mosaicVerticalDividerDrawable:
                setVerticalDividerDrawable(a.getDrawable(curAttr));
                break;
            case R.styleable.MosaicView_mosaicHorizontalDividerDrawable:
                setHorizontalDividerDrawable(a.getDrawable(curAttr));
                break;
            case R.styleable.MosaicView_mosaicShowDividers:
                setShowDivider(a.getInt(curAttr, SHOW_DIVIDER_NONE));
                break;
            }
        }
        a.recycle();
        //
        if (!isInEditMode())
            resetAllImageViews();
        else {
            final ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
            for (int i = 0; i < 4; ++i)
                bitmaps.add(BitmapFactory.decodeResource(getResources(), android.R.drawable.sym_def_app_icon));
            setImages(bitmaps);
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void setVerticalDividerDrawable(final Drawable drawable) {
        mVerticalDividerDrawable = drawable;
        mMainContainer.setDividerDrawable(drawable);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void setHorizontalDividerDrawable(final Drawable drawable) {
        mHorizontalDividerDrawable = drawable;
        mLeftContainer.setDividerDrawable(drawable);
        mRightContainer.setDividerDrawable(drawable);
    }

    public Drawable getVerticalDividerDrawable() {
        return this.mVerticalDividerDrawable;
    }

    public Drawable getHorizontalDividerDrawable() {
        return this.mHorizontalDividerDrawable;
    }

    public int getShowDivider() {
        return this.mShowDivider;
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void setShowDivider(final int dividers) {
        mShowDivider = dividers;
        int containersDividers = IcsLinearLayout.SHOW_DIVIDER_NONE;
        if ((dividers & SHOW_DIVIDER_INNER) != 0)
            containersDividers |= IcsLinearLayout.SHOW_DIVIDER_MIDDLE;
        if ((dividers & SHOW_DIVIDER_OUTER) != 0)
            containersDividers |= IcsLinearLayout.SHOW_DIVIDER_END | IcsLinearLayout.SHOW_DIVIDER_BEGINNING;
        mLeftContainer.setShowDividers(containersDividers);
        mRightContainer.setShowDividers(containersDividers);
        mMainContainer.setShowDividers(containersDividers);
    }

    private void resetAllImageViews() {
        mTopLeftImageView.setImageResource(0);
        mTopRightImageView.setImageResource(0);
        mBottomLeftImageView.setImageResource(0);
        mBottomRightImageView.setImageResource(0);
        mTopLeftImageView.setVisibility(View.GONE);
        mTopRightImageView.setVisibility(View.GONE);
        mBottomLeftImageView.setVisibility(View.GONE);
        mBottomRightImageView.setVisibility(View.GONE);
        mLeftContainer.setVisibility(View.GONE);
        mRightContainer.setVisibility(View.GONE);
    }

    public void setImages(final ArrayList<Bitmap> images) {
        resetAllImageViews();
        if (images == null || images.size() == 0)
            return;
        switch (images.size()) {
        case 1:
            mTopLeftImageView.setImageBitmap(images.get(0));
            mTopLeftImageView.setVisibility(View.VISIBLE);
            mLeftContainer.setVisibility(View.VISIBLE);
            break;
        case 2:
            mTopLeftImageView.setImageBitmap(images.get(0));
            mTopRightImageView.setImageBitmap(images.get(1));
            mTopLeftImageView.setVisibility(View.VISIBLE);
            mTopRightImageView.setVisibility(View.VISIBLE);
            mLeftContainer.setVisibility(View.VISIBLE);
            mRightContainer.setVisibility(View.VISIBLE);
            break;
        case 3:
            mTopLeftImageView.setImageBitmap(images.get(0));
            mTopRightImageView.setImageBitmap(images.get(1));
            mBottomRightImageView.setImageBitmap(images.get(2));
            mBottomRightImageView.setVisibility(View.VISIBLE);
            mTopLeftImageView.setVisibility(View.VISIBLE);
            mTopRightImageView.setVisibility(View.VISIBLE);
            mLeftContainer.setVisibility(View.VISIBLE);
            mRightContainer.setVisibility(View.VISIBLE);
            break;
        default:
            // TODO handle case of more than 4 images
        case 4:
            mTopLeftImageView.setImageBitmap(images.get(0));
            mTopRightImageView.setImageBitmap(images.get(1));
            mBottomRightImageView.setImageBitmap(images.get(2));
            mBottomLeftImageView.setImageBitmap(images.get(3));
            mBottomLeftImageView.setVisibility(View.VISIBLE);
            mBottomRightImageView.setVisibility(View.VISIBLE);
            mTopLeftImageView.setVisibility(View.VISIBLE);
            mTopRightImageView.setVisibility(View.VISIBLE);
            mLeftContainer.setVisibility(View.VISIBLE);
            mRightContainer.setVisibility(View.VISIBLE);
            break;
        }
    }

}

mosaic_view.xml:

mosaic_view.xml:

<com.actionbarsherlock.internal.widget.IcsLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mosaicView__mainContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <com.actionbarsherlock.internal.widget.IcsLinearLayout
        android:id="@+id/mosaicView__leftContainer"
        android:layout_width="0px"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/mosaicView__topLeftImageView"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:scaleType="centerCrop"
            android:src="@android:drawable/sym_def_app_icon" />

        <ImageView
            android:id="@+id/mosaicView__bottomLeftImageView"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:scaleType="centerCrop"
            android:src="@android:drawable/sym_def_app_icon" />
    </com.actionbarsherlock.internal.widget.IcsLinearLayout>

    <com.actionbarsherlock.internal.widget.IcsLinearLayout
        android:id="@+id/mosaicView__rightContainer"
        android:layout_width="0px"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/mosaicView__topRightImageView"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:scaleType="centerCrop"
            android:src="@android:drawable/sym_def_app_icon" />

        <ImageView
            android:id="@+id/mosaicView__bottomRightImageView"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:scaleType="centerCrop"
            android:src="@android:drawable/sym_def_app_icon" />
    </com.actionbarsherlock.internal.widget.IcsLinearLayout>

</com.actionbarsherlock.internal.widget.IcsLinearLayout>

attr.xml:

attr.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <declare-styleable name="MosaicView">
        <attr name="mosaicVerticalDividerDrawable" format="reference" />
        <attr name="mosaicHorizontalDividerDrawable" format="reference" />
        <attr name="mosaicShowDividers">
            <flag name="none" value="0x00" />
            <flag name="outer" value="0x01" />
            <flag name="inner" value="0x02" />
        </attr>
    </declare-styleable>

</resources>

这篇关于&QUOT;马赛克&QUOT; (分裂)图像 - Gmail的信件风格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆