'HoneyBee Hive View For android

Hello all can any one help me to create this view i am able to create this view static but i want this dynamic view , According to the data.Thanks

I have Try this but its seem not working like i want BeeHive View

Honey Bee Hive View



Solution 1:[1]

BeeHive Result

BeeHive

MainActivity file:

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.meg7.widget.CustomShapeImageView;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final Integer[] INVISIBLE = {1,2,6,10,11,19,20,25,29,30};// this array have cell number that hide in view
    private static final Integer[] INEMPTY = {4,5,9,15,16,21,26,28};// cell number that visible but it has no image(empty cell)
    private static final Integer[] NORMAL = {3,7,8,12,13,14,17,18,22,23,24,27};// normal cells

    private LinearLayout l_root;
    private List<CustomShapeImageView> photoViewList;// each cell view
    DisplayImageOptions options;

    private final static ImageLoader imageLoader = ImageLoader.getInstance();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initImageLoader(this);

        photoViewList=new ArrayList<>();
        options = new DisplayImageOptions.Builder()
                .imageScaleType(ImageScaleType.EXACTLY)
                .showStubImage(R.drawable.avatar)
                .showImageForEmptyUri(R.drawable.avatar)
                .cacheOnDisk(true).build();

        l_root =(LinearLayout)findViewById(R.id.l_root);
        l_root.setOrientation(LinearLayout.VERTICAL);


        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;  // device screen width

        //int height = size.y;
        addView(width);
        addImage();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);//Menu Resource, Menu
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/NishaJain24/BeeHiveAndroid"));
                startActivity(browserIntent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    @Override
    public void onClick(View v) {
        String url=v.getTag().toString();
        if (!url.equalsIgnoreCase("-1")){
            Toast.makeText(MainActivity.this,url,Toast.LENGTH_SHORT).show();
        }
    }

    /** ini universal image loader**/
    public static void initImageLoader(Context context) {
        // This configuration tuning is custom. You can tune every option, you may tune some of them,
        // or you can create default configuration by
        // ImageLoaderConfiguration.createDefault(this);
        // method.
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                //.writeDebugLogs() // Remove for release app
                .build();
        //Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config);

    }

    /** add image to each normal cells in order**/
    private void addImage() {

        for (int i = 0; (i < ImagesUrl.IMAGEURLS.length && (i < photoViewList.size())); i++) {
            String image = ImagesUrl.IMAGEURLS[i];
            photoViewList.get(i).setVisibility(View.VISIBLE);
            photoViewList.get(i).setTag(image);
            photoViewList.get(i).setOnClickListener(MainActivity.this);

            final int finalI = i;
            imageLoader.loadImage(image,options, new ImageLoadingListener() {
                @Override
                public void onLoadingStarted(String s, View view) {

                }

                @Override
                public void onLoadingFailed(String s, View view, FailReason failReason) {

                }

                @Override
                public void onLoadingComplete(String s, View view, Bitmap bitmap) {
                    photoViewList.get(finalI).setImageBitmap(bitmap);
                }

                @Override
                public void onLoadingCancelled(String s, View view) {

                }
            });
        }

    }

    /** created beehive view here**/
    private void addView(int width){

        int margin=-(width/8)/4;
        width =(width+(width/16))/4;

        photoViewList.clear();
        for (int j=0;j<=5;j++) {
            LinearLayout ll = new LinearLayout(MainActivity.this);
            ll.setOrientation(LinearLayout.HORIZONTAL);
            //ll.setBackgroundColor(Color.BLUE);
            LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    width);

            int marginLeft=(j%2 ==0)?(-(width/2)+margin):margin;
            int marginTop=(j !=0)?(-(width/5)):0;


            llParams.setMargins(marginLeft, marginTop, 0,0 );
            ll.setLayoutParams(llParams);

            for (int i=0;i<=5;i++) {
                int possition=j*5+i +1;

                FrameLayout l_farme = new FrameLayout(MainActivity.this);
                FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(width, width);
                FrameLayout.LayoutParams frameParams2 = new FrameLayout.LayoutParams(width-(width/10), width-(width/10));
                frameParams2.gravity = Gravity.CENTER;
                l_farme.setLayoutParams(frameParams);

                ImageView hexagon = new ImageView(MainActivity.this);
                hexagon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

                hexagon.setLayoutParams(frameParams);

                CustomShapeImageView photo=new CustomShapeImageView(MainActivity.this,R.drawable.avatar,
                        CustomShapeImageView.Shape.SVG,R.raw.hex);
                photo.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
                photo.setLayoutParams(frameParams2);

                hexagon.setImageResource(R.drawable.hexagon);
                photo.setVisibility(View.VISIBLE);
                l_farme.setVisibility(View.VISIBLE);
                hexagon.setVisibility(View.VISIBLE);
                if (Arrays.asList(INVISIBLE).contains(possition)){
                    l_farme.setVisibility(View.INVISIBLE);
                }else if (Arrays.asList(INEMPTY).contains(possition)){
                    photo.setVisibility(View.INVISIBLE);
                    l_farme.setVisibility(View.VISIBLE);
                }else if (Arrays.asList(NORMAL).contains(possition)){
                    l_farme.setVisibility(View.VISIBLE);
                    photo.setVisibility(View.INVISIBLE);
                    photo.setTag("-1");
                    photoViewList.add(photo);
                    //photo.setVisibility(View.VISIBLE);
                }

                l_farme.addView(photo);
                l_farme.addView(hexagon);
                ll.addView(l_farme);
            }
            l_root.addView(ll);
        }
    }

}

Create a java file for storing Image Url

public class ImagesUrl {
    public static final String[] IMAGEURLS={
            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa1sjJFmPQiHm0QBL_k6oxOL1ov2LvnriDAw&usqp=CAU",
            "https://i.pinimg.com/564x/e9/de/17/e9de175ab3987752fc5d2f49e729d391.jpg",
            "https://icons.iconarchive.com/icons/google/noto-emoji-people-face/1024/10135-boy-light-skin-tone-icon.png",
            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTKC3g0Ce32Jfxypb9t-KjcfbJ6oZOUCDFrYA&usqp=CAU",
            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmcBIbmP6D2QXQoXyEzZqkPuxDWFLCjYc40A&usqp=CAU",
            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTA1ex7y5sJf7RcvxwlHPhfGxEoS0qknjnoBQ&usqp=CAU",
            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSekJBSJPfDESTHcDw5cUlp2O3bmJ7zjMp5Wg&usqp=CAU",
            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTdyenRV1-qC8IV2Utxfm8VQhrXtpVRvpUZ2Q&usqp=CAU",
            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQX9iSSdnDdhfRK-H8o4M0XfQxagijAQT83AQ&usqp=CAU",
    };
}

Add internet permission in AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="10dp"
    android:paddingTop="10dp">

    <LinearLayout
        android:id="@+id/l_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    </LinearLayout>
</FrameLayout>

Create menu file and inside menu create a menu resource file

main_menu.xml file

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item  android:id="@+id/item1"
        android:icon="@drawable/ic_contact"
        app:showAsAction="always"
        android:title="more"/>
</menu>

build.gradle(app) file

plugins {
    id 'com.android.application'
}

android {
    compileSdk 31

    defaultConfig {
        applicationId "com.nishajain.beehiveandroid"
        minSdk 21
        targetSdk 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
    implementation 'com.mostafagazar:customshapeimageview:1.0.4'
}

For raw images and further code used in this example you can refer this link:

BeeHiveSourceCode

Solution 2:[2]

here is the solution to created dynamic number of hexagons with data after getting list from API.

arrayList.forEachIndexed { index, domeModel ->

        var rootLayout = ConstraintLayout(this)
        var layoutParams = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT)
        rootLayout.layoutParams = layoutParams

        var hexagonView = ImageView(this)
        hexagonView.scaleType = ImageView.ScaleType.CENTER_INSIDE
        hexagonView.layoutParams = LinearLayout.LayoutParams(100, 100)
        hexagonView.setImageResource(R.drawable.hexagon)
        hexagonView.setColorFilter(Color.argb(255, 255, 255, 255))
        hexagonView.setOnClickListener {

        }

        var singleCell = ImageView(this)
        var imageParams = LinearLayout.LayoutParams(100, 100)
        singleCell.setPadding(25, 25, 25, 25)
        singleCell.layoutParams = imageParams
        singleCell.scaleType = ImageView.ScaleType.CENTER_CROP
        singleCell.rotation = 270f

        if (index == 0) {
            layoutParams.circleRadius = 0
            layoutParams.circleAngle = 0f
            layoutParams.circleConstraint = binding.tvDome.id

            rootLayout.addView(hexagonView)
            rootLayout.addView(singleCell)
            binding.lRoot.addView(rootLayout)
        }
        if (index!= 0 && index < 7) {
            layoutParams.circleRadius = 120
            layoutParams.circleAngle = -270 + angle * (index - 1)
            layoutParams.circleConstraint = binding.tvDome.id

            rootLayout.addView(hexagonView)
            rootLayout.addView(singleCell)
            binding.lRoot.addView(rootLayout)

        } else if (index in 7..18) {

            layoutParams.circleAngle = angle2 * (index - 1)
            layoutParams.circleConstraint = binding.tvDome.id

            if (index % 2 != 0) {
                layoutParams.circleRadius = 200
            } else {
                layoutParams.circleRadius = 240
            }

            rootLayout.addView(hexagonView)
            rootLayout.addView(singleCell)
            binding.lRoot.addView(rootLayout)

        }
    }

xml file:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:rotation="90">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/l_root"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                tools:context="com.shijil.beehiveview.MainActivity">

                <androidx.appcompat.widget.AppCompatTextView
                    android:layout_width="@dimen/_200sdp"
                    android:layout_height="@dimen/_200sdp"
                    android:padding="@dimen/_16sdp"
                    android:rotation="270"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    android:id="@+id/tvDome"
                    android:textColor="@color/white"
                    android:textSize="@dimen/_10ssp"
                    android:gravity="center"/>

            </androidx.constraintlayout.widget.ConstraintLayout>
        </FrameLayout>

    </LinearLayout>

let me know if you face any problem with it

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nisha Jain
Solution 2 Satyam Kamboj