Celtic Knots

Click in the grid to make an element of a Celtic knot. The app decides what the element should look like to make a valid knot.

Stringsapp/res/values/strings.xml
Screen formatapp/res/layout/activity_main.xml
Code for appapp/java/com.(the project name)/MainActivity
Code for style gridviewapp/java/com.(the project name)/ImageStyle
Code for tile gridviewapp/java/com.(the project name)/ImageTile



app/manifests/AndroidManifest.xml - to force orientation

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.edkins.mosaic" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>


app/res/drawable - pictures

There are 6 x 16 image files (17 per style). The styles are "close", "loose", "stone", "simple", "roman" and "border" and the files are, e.g., "close0" (background) to "close16". They give the various parts of the knot. They are loaded into an arrays defined in in app/java/com.(the project name)/MainActivity and used in app/java/com.(the project name)/ImagePalette and app/java/com.(the project name)/ImageTile. The number of styles (6) is defined in app/java/com.(the project name)/MainActivity.




app/res/mipmap/ic_launcher.png/ - icon for launching app




app/res/values/strings.xml - strings

<resources> <string name="app_name">CelticKnots</string> <string name="howTo">Tap below to make knot, tap above to change style</string> <string name="clearMessage">new</string></resources>


app/res/layout/activity_main.xml - screen format

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <GridView android:id="@+id/styleView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numColumns="6" /> <TextView android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/howTo" android:layout_below="@id/styleView" /> <GridView android:id="@+id/tileView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="@dimen/activity_vertical_margin" android:numColumns="10" android:layout_below="@id/message" /> <Button android:id="@+id/clearButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/clearMessage" android:onClick="doClear" android:paddingTop="@dimen/activity_vertical_margin" android:layout_below="@id/tileView" /> </RelativeLayout>


app/java/com.(the project name)/MainActivity - main code for app

package com.edkins.celticknots; import ... public class MainActivity extends AppCompatActivity { // style of knot and number of styles public static int styleType = 0; public static int styleNum = 6; // tiles - for setting up tessera public static int [] tile = new int [100]; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); GridView style = (GridView) findViewById(R.id.styleView); style.setNumColumns(styleNum); style.setAdapter(new ImageStyle(this)); style.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { processStyleClick(position); } }); GridView tile = (GridView) findViewById(R.id.tileView); tile.setAdapter(new ImageTile(this)); tile.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { processTileClick(position); } }); } public void processStyleClick(int position) { styleType = position; redo(); } public void processTileClick(int position) { if (tile[position] == 0) {tile[position] = 1;} else {tile[position] = 0;} int y = position / 10; int x = position % 10; processTile(x, y); processTile(x-1, y); processTile(x+1, y); processTile(x, y-1); processTile(x, y+1); redo(); } public void processTile(int x, int y) { if (x<0 || x>9 || y<0 || y>9) {return;} int position = y*10 + x; if (tile[position]==0) {return;} int n = checkNext(x, y-1); int s = checkNext(x, y+1); int w = checkNext(x-1, y); int e = checkNext(x+1, y); if (n==0 && e==0 && s==0 && w==0) {tile[position] = 1;} else if (n==0 && e==0 && s==1 && w==0) {tile[position] = 2;} else if (n==0 && e==0 && s==0 && w==1) {tile[position] = 3;} else if (n==1 && e==0 && s==0 && w==0) {tile[position] = 4;} else if (n==0 && e==1 && s==0 && w==0) {tile[position] = 5;} else if (n==0 && e==1 && s==1 && w==0) {tile[position] = 6;} else if (n==0 && e==0 && s==1 && w==1) {tile[position] = 7;} else if (n==1 && e==0 && s==0 && w==1) {tile[position] = 8;} else if (n==1 && e==1 && s==0 && w==0) {tile[position] = 9;} else if (n==0 && e==1 && s==0 && w==1) {tile[position] = 10;} else if (n==1 && e==0 && s==1 && w==0) {tile[position] = 11;} else if (n==0 && e==1 && s==1 && w==1) {tile[position] = 12;} else if (n==1 && e==0 && s==1 && w==1) {tile[position] = 13;} else if (n==1 && e==1 && s==0 && w==1) {tile[position] = 14;} else if (n==1 && e==1 && s==1 && w==0) {tile[position] = 15;} else {tile[position] = 16;} } public int checkNext(int x, int y) { if (x<0 || x>9 || y<0 || y>9) {return 0;} int position = y*10 + x; if (tile [position]==0) {return 0;} else {return 1;} } public void doClear(View view) { for (int i=0; i<100; i++) {tile[i] = 0;} redo(); } // redo screen public void redo() { GridView tile = (GridView) findViewById(R.id.tileView); tile.setAdapter(new ImageTile(this)); } // Style - close knot public static Integer[] close = { R.drawable.close0, R.drawable.close1, R.drawable.close2, R.drawable.close3, R.drawable.close4, R.drawable.close5, R.drawable.close6, R.drawable.close7, R.drawable.close8, R.drawable.close9, R.drawable.close10, R.drawable.close11, R.drawable.close12, R.drawable.close13, R.drawable.close14, R.drawable.close15, R.drawable.close16 }; // Style - loose knot public static Integer[] loose = { R.drawable.loose0, R.drawable.loose1, R.drawable.loose2, R.drawable.loose3, R.drawable.loose4, R.drawable.loose5, R.drawable.loose6, R.drawable.loose7, R.drawable.loose8, R.drawable.loose9, R.drawable.loose10, R.drawable.loose11, R.drawable.loose12, R.drawable.loose13, R.drawable.loose14, R.drawable.loose15, R.drawable.loose16 }; // Style - stone knot public static Integer[] stone = { R.drawable.stone0, R.drawable.stone1, R.drawable.stone2, R.drawable.stone3, R.drawable.stone4, R.drawable.stone5, R.drawable.stone6, R.drawable.stone7, R.drawable.stone8, R.drawable.stone9, R.drawable.stone10, R.drawable.stone11, R.drawable.stone12, R.drawable.stone13, R.drawable.stone14, R.drawable.stone15, R.drawable.stone16 }; // Style - simple knot public static Integer[] simple = { R.drawable.simple0, R.drawable.simple1, R.drawable.simple2, R.drawable.simple3, R.drawable.simple4, R.drawable.simple5, R.drawable.simple6, R.drawable.simple7, R.drawable.simple8, R.drawable.simple9, R.drawable.simple10, R.drawable.simple11, R.drawable.simple12, R.drawable.simple13, R.drawable.simple14, R.drawable.simple15, R.drawable.simple16 }; // Style - Roman mosaic public static Integer[] roman = { R.drawable.roman0, R.drawable.roman1, R.drawable.roman2, R.drawable.roman3, R.drawable.roman4, R.drawable.roman5, R.drawable.roman6, R.drawable.roman7, R.drawable.roman8, R.drawable.roman9, R.drawable.roman10, R.drawable.roman11, R.drawable.roman12, R.drawable.roman13, R.drawable.roman14, R.drawable.roman15, R.drawable.roman16 }; // Style - knot with border public static Integer[] border = { R.drawable.border0, R.drawable.border1, R.drawable.border2, R.drawable.border3, R.drawable.border4, R.drawable.border5, R.drawable.border6, R.drawable.border7, R.drawable.border8, R.drawable.border9, R.drawable.border10, R.drawable.border11, R.drawable.border12, R.drawable.border13, R.drawable.border14, R.drawable.border15, R.drawable.border16 }; }


app/java/com.(the project name)/ImageStyle - code for palette gridview. You create this new file by right-clicking on the MainActvity and select New, then Java class

package com.edkins.celticknots; import ... public class ImageStyle extends BaseAdapter { private AppCompatActivity mContext; public ImageStyle(AppCompatActivity c) {mContext = c;} public int getCount() {return MainActivity.styleNum;} public Object getItem(int position) {return null;} public long getItemId(int position) {return 0;} // create new ImageView for palette public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { imageView = new ImageView(mContext); GridView style = (GridView) mContext.findViewById(R.id.styleView); int w = style.getWidth() / 7; imageView.setLayoutParams(new GridView.LayoutParams(w, w)); } else { imageView = (ImageView) convertView; } // initialise the view element (to one of the colours) if (position == 0) {imageView.setImageResource(R.drawable.close10);} else if (position == 1) {imageView.setImageResource(R.drawable.loose10);} else if (position == 2) {imageView.setImageResource(R.drawable.stone10);} else if (position == 3) {imageView.setImageResource(R.drawable.simple10);} else if (position == 4) {imageView.setImageResource(R.drawable.roman10);} else if (position == 5) {imageView.setImageResource(R.drawable.border10);} return imageView; } }


app/java/com.(the project name)/ImageTile - code for tile gridview - a new file, see above

package com.edkins.celticknots; import ... public class ImageTile extends BaseAdapter { private AppCompatActivity mContext; public ImageTile(AppCompatActivity c) {mContext = c;} public int getCount() {return 100;} public Object getItem(int position) {return null;} public long getItemId(int position) {return 0;} // create new ImageView for tile public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { imageView = new ImageView(mContext); GridView tile = (GridView) mContext.findViewById(R.id.tileView); int w = tile.getWidth() / 10; imageView.setLayoutParams(new GridView.LayoutParams(w, w)); } else { imageView = (ImageView) convertView; } // initialise the view element (to whatever is in array tile[]) int sub = MainActivity.tile[position]; if (MainActivity.styleType == 0) { imageView.setImageResource(MainActivity.close[sub]); } else if (MainActivity.styleType == 1) { imageView.setImageResource(MainActivity.loose[sub]); } else if (MainActivity.styleType == 2) { imageView.setImageResource(MainActivity.stone[sub]); } else if (MainActivity.styleType == 3) { imageView.setImageResource(MainActivity.simple[sub]); } else if (MainActivity.styleType == 4) { imageView.setImageResource(MainActivity.roman[sub]); } else if (MainActivity.styleType == 5) { imageView.setImageResource(MainActivity.border[sub]); } return imageView; } }


Index to my other websites

© Jo Edkins 2016