diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..d5518c1 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/README.md b/README.md index 40bdc1f..7efd823 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # TimetableView [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![API](https://img.shields.io/badge/API-19%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=19) -[![](https://jitpack.io/v/tlaabs/TimetableView.svg)](https://jitpack.io/#tlaabs/TimetableView) +[![](https://jitpack.io/v/omarb1989/TimetableView.svg)](https://jitpack.io/#omarb1989/TimetableView) Android Library that creates simple time table. +![dark](https://user-images.githubusercontent.com/9026030/128323499-f8562b86-8f18-4cc3-a6b5-3165b03ad88b.jpg) +![light](https://user-images.githubusercontent.com/9026030/128323528-678ceab1-4dd8-40e1-a09b-e66b98ed0343.jpg) -![img0](https://postfiles.pstatic.net/MjAxOTAxMjdfMTUz/MDAxNTQ4NTcyNTU5NTk4.M9hWyDvljjkoBDW-naLrTRqRAXUM8WRUyZXptTLKbs8g.b0FN12d8Cmxp5OWZqlQcusL_mJYNKgx6a_XLe_1ALOog.JPEG.tlaabs/Screenshot_Air.jpg?type=w773) -![img1](https://user-images.githubusercontent.com/8165219/62833150-b88d3180-bc74-11e9-9b20-02a0ad03e778.jpg) ## How to import @@ -23,7 +23,7 @@ allprojects { Add the dependency ```gradle dependencies { - implementation 'com.github.tlaabs:TimetableView:1.0.3-fx1' + implementation 'com.github.omarb1989:TimetableView:1.0.4-fx16' } ``` @@ -36,7 +36,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" ### TimetableView in layout ```xml - +``` + +**Force RTL Programmatically:** +```java +timetable.setRTL(true); // Enable RTL mode +timetable.setRTL(false); // Enable LTR mode +timetable.setRTL(null); // Revert to system auto-detection +``` + +**Or using Builder:** +```java +TimetableView timetable = new TimetableView.Builder(context) + .setForceRTL(true) + .build(); ``` ### Change header title @@ -73,7 +108,7 @@ First, write a string-array as below on values/strings.xml. ``` Then, apply that to timetable attribute. ```xml - schedules) { + + } + }); +``` ### Add schdule ```java ArrayList schedules = new ArrayList(); @@ -103,6 +149,7 @@ schedule.setClassPlace("IT-601"); // sets place schedule.setProfessorName("Won Kim"); // sets professor schedule.setStartTime(new Time(10,0)); // sets the beginning of class time (hour,minute) schedule.setEndTime(new Time(13,30)); // sets the end of class time (hour,minute) +int uniqueId = schedule.get_id();// you can use it later on wherever you get schedule object to identify it schedules.add(schedule); //.. add one or more schedules timetable.add(schedules); @@ -123,7 +170,7 @@ timetable.removeAll(); // remove all items ### Highlight header **1.Color type(Default)** ```xml - - + - + - + \ No newline at end of file diff --git a/app/src/main/java/com/github/tlaabs/timetableviewdemo/EditActivity.java b/app/src/main/java/com/github/omarb1989/timetableviewdemo/EditActivity.java similarity index 79% rename from app/src/main/java/com/github/tlaabs/timetableviewdemo/EditActivity.java rename to app/src/main/java/com/github/omarb1989/timetableviewdemo/EditActivity.java index f98b153..b5c3c96 100644 --- a/app/src/main/java/com/github/tlaabs/timetableviewdemo/EditActivity.java +++ b/app/src/main/java/com/github/omarb1989/timetableviewdemo/EditActivity.java @@ -1,9 +1,9 @@ -package com.github.tlaabs.timetableviewdemo; +package com.github.omarb1989.timetableviewdemo; import android.app.TimePickerDialog; import android.content.Context; import android.content.Intent; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; @@ -13,8 +13,8 @@ import android.widget.TextView; import android.widget.TimePicker; -import com.github.tlaabs.timetableview.Schedule; -import com.github.tlaabs.timetableview.Time; +import com.github.omarb1989.timetableview.Schedule; +import com.github.omarb1989.timetableview.Time; import java.util.ArrayList; @@ -128,35 +128,33 @@ public void onTimeSet(TimePicker view, int hourOfDay, int minute) { @Override public void onClick(View v) { - switch (v.getId()){ - case R.id.submit_btn: - if(mode == MainActivity.REQUEST_ADD){ - inputDataProcessing(); - Intent i = new Intent(); - ArrayList schedules = new ArrayList(); - //you can add more schedules to ArrayList - schedules.add(schedule); - i.putExtra("schedules",schedules); - setResult(RESULT_OK_ADD,i); - finish(); - } - else if(mode == MainActivity.REQUEST_EDIT){ - inputDataProcessing(); - Intent i = new Intent(); - ArrayList schedules = new ArrayList(); - schedules.add(schedule); - i.putExtra("idx",editIdx); - i.putExtra("schedules",schedules); - setResult(RESULT_OK_EDIT,i); - finish(); - } - break; - case R.id.delete_btn: + int id = v.getId(); + if (id == R.id.submit_btn) { + if(mode == MainActivity.REQUEST_ADD){ + inputDataProcessing(); + Intent i = new Intent(); + ArrayList schedules = new ArrayList(); + //you can add more schedules to ArrayList + schedules.add(schedule); + i.putExtra("schedules",schedules); + setResult(RESULT_OK_ADD,i); + finish(); + } + else if(mode == MainActivity.REQUEST_EDIT){ + inputDataProcessing(); Intent i = new Intent(); + ArrayList schedules = new ArrayList(); + schedules.add(schedule); i.putExtra("idx",editIdx); - setResult(RESULT_OK_DELETE, i); + i.putExtra("schedules",schedules); + setResult(RESULT_OK_EDIT,i); finish(); - break; + } + } else if (id == R.id.delete_btn) { + Intent i = new Intent(); + i.putExtra("idx",editIdx); + setResult(RESULT_OK_DELETE, i); + finish(); } } diff --git a/app/src/main/java/com/github/omarb1989/timetableviewdemo/MainActivity.java b/app/src/main/java/com/github/omarb1989/timetableviewdemo/MainActivity.java new file mode 100644 index 0000000..f086646 --- /dev/null +++ b/app/src/main/java/com/github/omarb1989/timetableviewdemo/MainActivity.java @@ -0,0 +1,142 @@ +package com.github.omarb1989.timetableviewdemo; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.res.ResourcesCompat; + +import com.github.omarb1989.timetableview.Schedule; +import com.github.omarb1989.timetableview.TimetableView; + +import java.util.ArrayList; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener { + private Context context; + public static final int REQUEST_ADD = 1; + public static final int REQUEST_EDIT = 2; + + private Button addBtn; + private Button clearBtn; + private Button saveBtn; + private Button loadBtn; + + private TimetableView timetable; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + init(); + timetable.setOnStickerSelectEventListener(new TimetableView.OnStickerSelectedLongClickListener() { + @Override + public void OnStickerSelectedLongClick(int idx, ArrayList schedules) { + //Toast.makeText(context, "LongClick idx = " + idx, Toast.LENGTH_SHORT).show(); + } + }); + // timetable.setBackgroundColor(ResourcesCompat.getColor(getResources(),R.color.default_sticker_font_color)); + + } + + private void init() { + this.context = this; + addBtn = findViewById(R.id.add_btn); + clearBtn = findViewById(R.id.clear_btn); + saveBtn = findViewById(R.id.save_btn); + loadBtn = findViewById(R.id.load_btn); + + timetable = findViewById(R.id.timetable); + timetable.setHeaderHighlight(2); + initView(); + } + + private void initView() { + addBtn.setOnClickListener(this); + clearBtn.setOnClickListener(this); + saveBtn.setOnClickListener(this); + loadBtn.setOnClickListener(this); + + timetable.setOnStickerSelectEventListener(new TimetableView.OnStickerSelectedListener() { + @Override + public void OnStickerSelected(int idx, ArrayList schedules) { + //Toast.makeText(context, "idx = " + idx, Toast.LENGTH_SHORT).show(); + Intent i = new Intent(context, EditActivity.class); + i.putExtra("mode", REQUEST_EDIT); + i.putExtra("idx", idx); + i.putExtra("schedules", schedules); + startActivityForResult(i, REQUEST_EDIT); + } + }); + } + + @Override + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.add_btn) { + Intent i = new Intent(this, EditActivity.class); + i.putExtra("mode", REQUEST_ADD); + startActivityForResult(i, REQUEST_ADD); + } else if (id == R.id.clear_btn) { + timetable.removeAll(); + } else if (id == R.id.save_btn) { + saveByPreference(timetable.createSaveData()); + } else if (id == R.id.load_btn) { + loadSavedData(); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + switch (requestCode) { + case REQUEST_ADD: + if (resultCode == EditActivity.RESULT_OK_ADD) { + ArrayList item = (ArrayList) data.getSerializableExtra("schedules"); + timetable.add(item); + } + break; + case REQUEST_EDIT: + /** Edit -> Submit */ + if (resultCode == EditActivity.RESULT_OK_EDIT) { + int idx = data.getIntExtra("idx", -1); + ArrayList item = (ArrayList) data.getSerializableExtra("schedules"); + timetable.edit(idx, item); + } + /** Edit -> Delete */ + else if (resultCode == EditActivity.RESULT_OK_DELETE) { + int idx = data.getIntExtra("idx", -1); + timetable.remove(idx); + } + break; + } + } + + /** + * save timetableView's data to SharedPreferences in json format + */ + private void saveByPreference(String data) { + SharedPreferences mPref = getSharedPreferences("timetable_demo_pref", MODE_PRIVATE); + SharedPreferences.Editor editor = mPref.edit(); + editor.putString("timetable_demo", data); + editor.commit(); + Toast.makeText(this, "saved!", Toast.LENGTH_SHORT).show(); + } + + /** + * get json data from SharedPreferences and then restore the timetable + */ + private void loadSavedData() { + timetable.removeAll(); + SharedPreferences mPref = getSharedPreferences("timetable_demo_pref", MODE_PRIVATE); + String savedData = mPref.getString("timetable_demo", ""); + if (savedData == null || savedData.equals("")) return; + timetable.load(savedData); + Toast.makeText(this, "loaded!", Toast.LENGTH_SHORT).show(); + } +} diff --git a/app/src/main/java/com/github/tlaabs/timetableviewdemo/MainActivity.java b/app/src/main/java/com/github/tlaabs/timetableviewdemo/MainActivity.java deleted file mode 100644 index 75cce12..0000000 --- a/app/src/main/java/com/github/tlaabs/timetableviewdemo/MainActivity.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.github.tlaabs.timetableviewdemo; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.Toast; - -import com.github.tlaabs.timetableview.Schedule; -import com.github.tlaabs.timetableview.TimetableView; - -import java.util.ArrayList; - -public class MainActivity extends AppCompatActivity implements View.OnClickListener { - private Context context; - public static final int REQUEST_ADD = 1; - public static final int REQUEST_EDIT = 2; - - private Button addBtn; - private Button clearBtn; - private Button saveBtn; - private Button loadBtn; - - private TimetableView timetable; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - init(); - } - - private void init(){ - this.context = this; - addBtn = findViewById(R.id.add_btn); - clearBtn = findViewById(R.id.clear_btn); - saveBtn = findViewById(R.id.save_btn); - loadBtn = findViewById(R.id.load_btn); - - timetable = findViewById(R.id.timetable); - timetable.setHeaderHighlight(2); - initView(); - } - - private void initView(){ - addBtn.setOnClickListener(this); - clearBtn.setOnClickListener(this); - saveBtn.setOnClickListener(this); - loadBtn.setOnClickListener(this); - - timetable.setOnStickerSelectEventListener(new TimetableView.OnStickerSelectedListener() { - @Override - public void OnStickerSelected(int idx, ArrayList schedules) { - Intent i = new Intent(context, EditActivity.class); - i.putExtra("mode",REQUEST_EDIT); - i.putExtra("idx", idx); - i.putExtra("schedules", schedules); - startActivityForResult(i,REQUEST_EDIT); - } - }); - } - - @Override - public void onClick(View v) { - switch (v.getId()){ - case R.id.add_btn: - Intent i = new Intent(this,EditActivity.class); - i.putExtra("mode",REQUEST_ADD); - startActivityForResult(i,REQUEST_ADD); - break; - case R.id.clear_btn: - timetable.removeAll(); - break; - case R.id.save_btn: - saveByPreference(timetable.createSaveData()); - break; - case R.id.load_btn: - loadSavedData(); - break; - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - switch (requestCode){ - case REQUEST_ADD: - if(resultCode == EditActivity.RESULT_OK_ADD){ - ArrayList item = (ArrayList)data.getSerializableExtra("schedules"); - timetable.add(item); - } - break; - case REQUEST_EDIT: - /** Edit -> Submit */ - if(resultCode == EditActivity.RESULT_OK_EDIT){ - int idx = data.getIntExtra("idx",-1); - ArrayList item = (ArrayList)data.getSerializableExtra("schedules"); - timetable.edit(idx,item); - } - /** Edit -> Delete */ - else if(resultCode == EditActivity.RESULT_OK_DELETE){ - int idx = data.getIntExtra("idx",-1); - timetable.remove(idx); - } - break; - } - } - - /** save timetableView's data to SharedPreferences in json format */ - private void saveByPreference(String data){ - SharedPreferences mPref = PreferenceManager.getDefaultSharedPreferences(this); - SharedPreferences.Editor editor = mPref.edit(); - editor.putString("timetable_demo",data); - editor.commit(); - Toast.makeText(this,"saved!",Toast.LENGTH_SHORT).show(); - } - - /** get json data from SharedPreferences and then restore the timetable */ - private void loadSavedData(){ - timetable.removeAll(); - SharedPreferences mPref = PreferenceManager.getDefaultSharedPreferences(this); - String savedData = mPref.getString("timetable_demo",""); - if(savedData == null && savedData.equals("")) return; - timetable.load(savedData); - Toast.makeText(this,"loaded!",Toast.LENGTH_SHORT).show(); - } -} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index aeafffd..a5d8ab8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -41,13 +41,21 @@ - + app:header_title="@array/header_title"/> + + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/com/github/tlaabs/timetableviewdemo/ExampleUnitTest.java b/app/src/test/java/com/github/omarb1989/timetableviewdemo/ExampleUnitTest.java similarity index 87% rename from app/src/test/java/com/github/tlaabs/timetableviewdemo/ExampleUnitTest.java rename to app/src/test/java/com/github/omarb1989/timetableviewdemo/ExampleUnitTest.java index 0eae514..ff041b6 100644 --- a/app/src/test/java/com/github/tlaabs/timetableviewdemo/ExampleUnitTest.java +++ b/app/src/test/java/com/github/omarb1989/timetableviewdemo/ExampleUnitTest.java @@ -1,4 +1,4 @@ -package com.github.tlaabs.timetableviewdemo; +package com.github.omarb1989.timetableviewdemo; import org.junit.Test; diff --git a/build.gradle b/build.gradle index 33e26a2..27dee28 100644 --- a/build.gradle +++ b/build.gradle @@ -1,27 +1,23 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' - classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + classpath 'com.android.tools.build:gradle:8.5.2' } } allprojects { repositories { google() - jcenter() + mavenCentral() + maven { url 'https://jitpack.io' } } } task clean(type: Delete) { - delete rootProject.buildDir + delete rootProject.layout.buildDirectory } diff --git a/gradle.properties b/gradle.properties index 82618ce..527fab2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,10 +6,10 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true +android.suppressUnsupportedCompileSdk=35 org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true + diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 70ed17f..93b330d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Aug 11 18:04:07 KST 2019 +#Sat Aug 01 10:34:24 CET 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..efde7bf --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - openjdk17 diff --git a/timetableview/build.gradle b/timetableview/build.gradle index eb6f9e6..0a82af4 100644 --- a/timetableview/build.gradle +++ b/timetableview/build.gradle @@ -1,36 +1,54 @@ apply plugin: 'com.android.library' +apply plugin: 'maven-publish' android { - compileSdkVersion 28 + namespace 'com.github.omarb1989.timetableview' + compileSdk 35 defaultConfig { - minSdkVersion 19 - targetSdkVersion 28 - versionCode 3 - versionName "1.0.3" - - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + minSdk 19 + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } buildTypes { release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + publishing { + singleVariant('release') { + withSourcesJar() } } +} +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + groupId = 'com.github.omarb1989' + artifactId = 'TimetableView' + version = '1.0.4-fx16' + } + } + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:28.0.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'androidx.appcompat:appcompat:1.6.1' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.google.code.gson:gson:2.10.1' } -apply plugin: 'com.github.dcendents.android-maven' -group='com.github.tlaabs' \ No newline at end of file diff --git a/timetableview/src/androidTest/java/com/github/tlaabs/timetableview/ExampleInstrumentedTest.java b/timetableview/src/androidTest/java/com/github/omarb1989/timetableview/ExampleInstrumentedTest.java similarity index 68% rename from timetableview/src/androidTest/java/com/github/tlaabs/timetableview/ExampleInstrumentedTest.java rename to timetableview/src/androidTest/java/com/github/omarb1989/timetableview/ExampleInstrumentedTest.java index 60498f1..226c2e2 100644 --- a/timetableview/src/androidTest/java/com/github/tlaabs/timetableview/ExampleInstrumentedTest.java +++ b/timetableview/src/androidTest/java/com/github/omarb1989/timetableview/ExampleInstrumentedTest.java @@ -1,8 +1,8 @@ -package com.github.tlaabs.timetableview; +package com.github.omarb1989.timetableview; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @@ -19,7 +19,7 @@ public class ExampleInstrumentedTest { @Test public void useAppContext() { // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); assertEquals("com.github.devsim.timetableview.test", appContext.getPackageName()); } diff --git a/timetableview/src/main/AndroidManifest.xml b/timetableview/src/main/AndroidManifest.xml index 908ce02..94cbbcf 100644 --- a/timetableview/src/main/AndroidManifest.xml +++ b/timetableview/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - + diff --git a/timetableview/src/main/java/com/github/omarb1989/timetableview/BorderWidth.java b/timetableview/src/main/java/com/github/omarb1989/timetableview/BorderWidth.java new file mode 100644 index 0000000..becfe28 --- /dev/null +++ b/timetableview/src/main/java/com/github/omarb1989/timetableview/BorderWidth.java @@ -0,0 +1,5 @@ +package com.github.omarb1989.timetableview; + +public enum BorderWidth { + NO_WIDTH,LIGHT,NORMAL,THICK,EXTRA_THICK +} diff --git a/timetableview/src/main/java/com/github/tlaabs/timetableview/HighlightMode.java b/timetableview/src/main/java/com/github/omarb1989/timetableview/HighlightMode.java similarity index 54% rename from timetableview/src/main/java/com/github/tlaabs/timetableview/HighlightMode.java rename to timetableview/src/main/java/com/github/omarb1989/timetableview/HighlightMode.java index dfa98a2..31b92de 100644 --- a/timetableview/src/main/java/com/github/tlaabs/timetableview/HighlightMode.java +++ b/timetableview/src/main/java/com/github/omarb1989/timetableview/HighlightMode.java @@ -1,4 +1,4 @@ -package com.github.tlaabs.timetableview; +package com.github.omarb1989.timetableview; public enum HighlightMode { COLOR, diff --git a/timetableview/src/main/java/com/github/tlaabs/timetableview/SaveManager.java b/timetableview/src/main/java/com/github/omarb1989/timetableview/SaveManager.java similarity index 96% rename from timetableview/src/main/java/com/github/tlaabs/timetableview/SaveManager.java rename to timetableview/src/main/java/com/github/omarb1989/timetableview/SaveManager.java index de62c9a..05945d7 100644 --- a/timetableview/src/main/java/com/github/tlaabs/timetableview/SaveManager.java +++ b/timetableview/src/main/java/com/github/omarb1989/timetableview/SaveManager.java @@ -1,6 +1,4 @@ -package com.github.tlaabs.timetableview; - -import android.util.Log; +package com.github.omarb1989.timetableview; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -23,6 +21,7 @@ public static String saveSticker(HashMap stickers){ ArrayList schedules = stickers.get(idx).getSchedules(); for(Schedule schedule : schedules){ JsonObject obj3 = new JsonObject(); + obj3.addProperty("_id",schedule._id); obj3.addProperty("classTitle",schedule.classTitle); obj3.addProperty("classPlace",schedule.classPlace); obj3.addProperty("professorName",schedule.getProfessorName()); @@ -57,6 +56,7 @@ public static HashMap loadSticker(String json){ for(int k = 0 ; k < arr2.size(); k++){ Schedule schedule = new Schedule(); JsonObject obj3 = (JsonObject)arr2.get(k); + schedule.set_id(obj3.get("_id").getAsInt()); schedule.setClassTitle(obj3.get("classTitle").getAsString()); schedule.setClassPlace(obj3.get("classPlace").getAsString()); schedule.setProfessorName(obj3.get("professorName").getAsString()); diff --git a/timetableview/src/main/java/com/github/tlaabs/timetableview/Schedule.java b/timetableview/src/main/java/com/github/omarb1989/timetableview/Schedule.java similarity index 81% rename from timetableview/src/main/java/com/github/tlaabs/timetableview/Schedule.java rename to timetableview/src/main/java/com/github/omarb1989/timetableview/Schedule.java index 64c7815..e4cc168 100644 --- a/timetableview/src/main/java/com/github/tlaabs/timetableview/Schedule.java +++ b/timetableview/src/main/java/com/github/omarb1989/timetableview/Schedule.java @@ -1,4 +1,4 @@ -package com.github.tlaabs.timetableview; +package com.github.omarb1989.timetableview; import java.io.Serializable; @@ -11,9 +11,11 @@ public class Schedule implements Serializable { static final int SAT = 5; static final int SUN = 6; - String classTitle=""; - String classPlace=""; - String professorName=""; + + int _id; + String classTitle = ""; + String classPlace = ""; + String professorName = ""; private int day = 0; private Time startTime; private Time endTime; @@ -21,6 +23,15 @@ public class Schedule implements Serializable { public Schedule() { this.startTime = new Time(); this.endTime = new Time(); + _id = (int) System.currentTimeMillis(); + } + + public int get_id() { + return _id; + } + + public void set_id(int _id) { + this._id = _id; } public String getProfessorName() { diff --git a/timetableview/src/main/java/com/github/tlaabs/timetableview/Sticker.java b/timetableview/src/main/java/com/github/omarb1989/timetableview/Sticker.java similarity index 93% rename from timetableview/src/main/java/com/github/tlaabs/timetableview/Sticker.java rename to timetableview/src/main/java/com/github/omarb1989/timetableview/Sticker.java index 6a32e39..17382b1 100644 --- a/timetableview/src/main/java/com/github/tlaabs/timetableview/Sticker.java +++ b/timetableview/src/main/java/com/github/omarb1989/timetableview/Sticker.java @@ -1,4 +1,4 @@ -package com.github.tlaabs.timetableview; +package com.github.omarb1989.timetableview; import android.widget.TextView; diff --git a/timetableview/src/main/java/com/github/tlaabs/timetableview/Time.java b/timetableview/src/main/java/com/github/omarb1989/timetableview/Time.java similarity index 92% rename from timetableview/src/main/java/com/github/tlaabs/timetableview/Time.java rename to timetableview/src/main/java/com/github/omarb1989/timetableview/Time.java index e9272e1..6f213d4 100644 --- a/timetableview/src/main/java/com/github/tlaabs/timetableview/Time.java +++ b/timetableview/src/main/java/com/github/omarb1989/timetableview/Time.java @@ -1,4 +1,4 @@ -package com.github.tlaabs.timetableview; +package com.github.omarb1989.timetableview; import java.io.Serializable; diff --git a/timetableview/src/main/java/com/github/omarb1989/timetableview/TimetableView.java b/timetableview/src/main/java/com/github/omarb1989/timetableview/TimetableView.java new file mode 100644 index 0000000..d38b33d --- /dev/null +++ b/timetableview/src/main/java/com/github/omarb1989/timetableview/TimetableView.java @@ -0,0 +1,762 @@ +package com.github.omarb1989.timetableview; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.graphics.Point; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.ShapeDrawable; +import android.util.AttributeSet; +import android.util.Log; +import android.util.TypedValue; +import android.view.Display; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TextView; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.res.ResourcesCompat; +import androidx.core.view.ViewCompat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +public class TimetableView extends LinearLayout { + private static final int DEFAULT_ROW_COUNT = 12; + private static final int DEFAULT_COLUMN_COUNT = 6; + private static final int DEFAULT_CELL_HEIGHT_DP = 50; + private static final int DEFAULT_SIDE_CELL_WIDTH_DP = 30; + private static final int DEFAULT_START_TIME = 8; + + private static final int DEFAULT_SIDE_HEADER_FONT_SIZE_DP = 13; + private static final int DEFAULT_HEADER_FONT_SIZE_DP = 15; + private static final int DEFAULT_HEADER_HIGHLIGHT_FONT_SIZE_DP = 15; + private static final int DEFAULT_STICKER_FONT_SIZE_DP = 13; + + + private int rowCount; + private int columnCount; + private int cellHeight; + private int sideCellWidth; + private String[] headerTitle; + private String[] stickerColors; + private int startTime; + private int headerHighlightColor; + private int colorSurface; + private int colorBorders; + private int sideColorText; + private int sideColor; + private int sideAndHeaderTextColor; + private int borderWidth; + private boolean isRTL; + private Boolean forceRTL = null; + + private RelativeLayout stickerBox; + TableLayout tableHeader; + TableLayout tableBox; + + private Context context; + + HashMap stickers = new HashMap(); + private int stickerCount = -1; + + private OnStickerSelectedListener stickerSelectedListener = null; + private OnStickerSelectedLongClickListener stickerSelectedLongClickListener = null; + + private HighlightMode highlightMode = HighlightMode.COLOR; + private int headerHighlightImageSize; + private Drawable headerHighlightImage = null; + + public TimetableView(Context context) { + super(context, null); + this.context = context; + } + + public TimetableView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public TimetableView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + this.context = context; + getAttrs(attrs); + init(); + } + + private void getAttrs(AttributeSet attrs) { + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TimetableView); + rowCount = a.getInt(R.styleable.TimetableView_row_count, DEFAULT_ROW_COUNT) - 1; + columnCount = a.getInt(R.styleable.TimetableView_column_count, DEFAULT_COLUMN_COUNT); + cellHeight = a.getDimensionPixelSize(R.styleable.TimetableView_cell_height, dp2Px(DEFAULT_CELL_HEIGHT_DP)); + sideCellWidth = a.getDimensionPixelSize(R.styleable.TimetableView_side_cell_width, dp2Px(DEFAULT_SIDE_CELL_WIDTH_DP)); + int titlesId = a.getResourceId(R.styleable.TimetableView_header_title, R.array.default_header_title); + headerTitle = a.getResources().getStringArray(titlesId); + int colorsId = a.getResourceId(R.styleable.TimetableView_sticker_colors, R.array.default_sticker_color); + stickerColors = a.getResources().getStringArray(colorsId); + startTime = a.getInt(R.styleable.TimetableView_start_time, DEFAULT_START_TIME); + headerHighlightColor = a.getColor(R.styleable.TimetableView_header_highlight_color, getResources().getColor(R.color.default_header_highlight_color)); + int highlightTypeValue = a.getInteger(R.styleable.TimetableView_header_highlight_type, 0); + if (highlightTypeValue == 0) highlightMode = HighlightMode.COLOR; + else if (highlightTypeValue == 1) highlightMode = HighlightMode.IMAGE; + headerHighlightImageSize = a.getDimensionPixelSize(R.styleable.TimetableView_header_highlight_image_size, dp2Px(24)); + headerHighlightImage = a.getDrawable(R.styleable.TimetableView_header_highlight_image); + colorSurface = a.getColor(R.styleable.TimetableView_color_surface, getResources().getColor(R.color.default_color_surface)); + colorBorders = a.getColor(R.styleable.TimetableView_color_borders, getResources().getColor(R.color.colorBorders)); + sideColorText = a.getColor(R.styleable.TimetableView_side_color_text, getResources().getColor(R.color.default_color_side_text)); + sideColor = a.getColor(R.styleable.TimetableView_color_side, getResources().getColor(R.color.colorSideHeader)); + sideAndHeaderTextColor = a.getColor(R.styleable.TimetableView_color_side_header_text, getResources().getColor(R.color.default_color_side_header_text)); + borderWidth = a.getInt(R.styleable.TimetableView_border_width, BorderWidth.NORMAL.ordinal()); + if (a.hasValue(R.styleable.TimetableView_force_rtl)) { + forceRTL = a.getBoolean(R.styleable.TimetableView_force_rtl, false); + } + a.recycle(); + } + + private boolean isLayoutRtl() { + if (forceRTL != null) { + return forceRTL; + } + // Check via Context Configuration — reliable even before view is attached to window + if (context != null && context.getResources() != null && context.getResources().getConfiguration() != null) { + return context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + } + return false; + } + + private void init() { + LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = layoutInflater.inflate(R.layout.view_timetable, this, false); + addView(view); + + stickerBox = view.findViewById(R.id.sticker_box); + tableHeader = view.findViewById(R.id.table_header); + tableBox = view.findViewById(R.id.table_box); + + isRTL = isLayoutRtl(); + + // IMPORTANT: We manage RTL layout physically (by child insertion order). + // Force LTR on table containers so Android does NOT auto-mirror them, + // which would undo our intentionally reversed column order. + ViewCompat.setLayoutDirection(tableHeader, ViewCompat.LAYOUT_DIRECTION_LTR); + ViewCompat.setLayoutDirection(tableBox, ViewCompat.LAYOUT_DIRECTION_LTR); + + Log.d("TimetableView", "init() forceRTL=" + forceRTL + + " isRTL=" + isRTL + + " configDir=" + (context != null ? context.getResources().getConfiguration().getLayoutDirection() : -1) + + " columnCount=" + columnCount); + + createTable(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + boolean currentRtl = isLayoutRtl(); + if (currentRtl != isRTL) { + isRTL = currentRtl; + rebuildTable(); + } + } + + /** + * Programmatically set RTL mode. + * Pass null to revert to auto-detection. + */ + public void setRTL(Boolean rtl) { + this.forceRTL = rtl; + boolean currentRtl = isLayoutRtl(); + if (currentRtl != this.isRTL) { + this.isRTL = currentRtl; + rebuildTable(); + } + } + + private void rebuildTable() { + // Re-force LTR on table containers every rebuild + ViewCompat.setLayoutDirection(tableHeader, ViewCompat.LAYOUT_DIRECTION_LTR); + ViewCompat.setLayoutDirection(tableBox, ViewCompat.LAYOUT_DIRECTION_LTR); + + if (tableHeader != null) tableHeader.removeAllViews(); + if (tableBox != null) tableBox.removeAllViews(); + createTable(); + repositionStickers(); + } + + /** + * Returns whether the timetable is currently in RTL mode. + */ + public boolean isRTL() { + return isRTL; + } + + public void setOnStickerSelectEventListener(OnStickerSelectedListener listener) { + stickerSelectedListener = listener; + } + + public void setOnStickerSelectEventListener(OnStickerSelectedLongClickListener listener) { + stickerSelectedLongClickListener = listener; + } + + + /** + * date : 2019-02-08 + * get all schedules TimetableView has. + */ + public ArrayList getAllSchedulesInStickers() { + ArrayList allSchedules = new ArrayList(); + for (int key : stickers.keySet()) { + for (Schedule schedule : stickers.get(key).getSchedules()) { + allSchedules.add(schedule); + } + } + return allSchedules; + } + + /** + * date : 2019-02-08 + * Used in Edit mode, To check a invalidate schedule. + */ + public ArrayList getAllSchedulesInStickersExceptIdx(int idx) { + ArrayList allSchedules = new ArrayList(); + for (int key : stickers.keySet()) { + if (idx == key) continue; + for (Schedule schedule : stickers.get(key).getSchedules()) { + allSchedules.add(schedule); + } + } + return allSchedules; + } + + public void add(ArrayList schedules) { + add(schedules, -1); + } + + private void add(final ArrayList schedules, int specIdx) { + final int count = specIdx < 0 ? ++stickerCount : specIdx; + Sticker sticker = new Sticker(); + for (Schedule schedule : schedules) { + TextView tv = new TextView(context); + + RelativeLayout.LayoutParams param = createStickerParam(schedule); + tv.setLayoutParams(param); + tv.setPadding(10, 0, 10, 0); + tv.setText(schedule.getClassTitle() + "\n" + schedule.getClassPlace()); + tv.setTextColor(Color.parseColor("#FFFFFF")); + tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_STICKER_FONT_SIZE_DP); + tv.setTypeface(null, Typeface.BOLD); + tv.setGravity(Gravity.CENTER); + + tv.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (stickerSelectedListener != null) + stickerSelectedListener.OnStickerSelected(count, schedules); + } + }); + tv.setOnLongClickListener(new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (stickerSelectedLongClickListener != null) + stickerSelectedLongClickListener.OnStickerSelectedLongClick(count, schedules); + return true; + } + }); + + + sticker.addTextView(tv); + sticker.addSchedule(schedule); + stickers.put(count, sticker); + stickerBox.addView(tv); + } + setStickerColor(); + } + + public String createSaveData() { + return SaveManager.saveSticker(stickers); + } + + public void load(String data) { + removeAll(); + stickers = SaveManager.loadSticker(data); + int maxKey = 0; + for (int key : stickers.keySet()) { + ArrayList schedules = stickers.get(key).getSchedules(); + add(schedules, key); + if (maxKey < key) maxKey = key; + } + stickerCount = maxKey + 1; + setStickerColor(); + } + + public void removeAll() { + for (int key : stickers.keySet()) { + Sticker sticker = stickers.get(key); + for (TextView tv : sticker.getView()) { + stickerBox.removeView(tv); + } + } + stickers.clear(); + } + + public void edit(int idx, ArrayList schedules) { + remove(idx); + add(schedules, idx); + } + + public void remove(int idx) { + Sticker sticker = stickers.get(idx); + for (TextView tv : sticker.getView()) { + stickerBox.removeView(tv); + } + stickers.remove(idx); + setStickerColor(); + } + + public void setHeaderHighlight(int idx) { + if (idx < 0) return; + // idx 0 is the Time/side column. In RTL it is the last physical child. + // idx 1+ are day columns. In RTL day 1 maps to child (columnCount - 2), etc. + int physicalIdx; + if (isRTL) { + // Time column (idx=0) is at the last position + if (idx == 0) { + physicalIdx = columnCount - 1; + } else { + // Day idx 1 → physical child (columnCount - 1 - idx) + physicalIdx = columnCount - 1 - idx; + } + } else { + physicalIdx = idx; + } + TableRow row = (TableRow) tableHeader.getChildAt(0); + View element = row.getChildAt(physicalIdx); + if (highlightMode == HighlightMode.COLOR) { + TextView tx = (TextView) element; + tx.setTextColor(Color.parseColor("#FFFFFF")); + tx.setBackgroundColor(headerHighlightColor); + tx.setTypeface(null, Typeface.BOLD); + tx.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEADER_HIGHLIGHT_FONT_SIZE_DP); + } else if (highlightMode == HighlightMode.IMAGE) { + RelativeLayout outer = new RelativeLayout(context); + outer.setLayoutParams(createTableRowParam(cellHeight)); + ImageView iv = new ImageView(context); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(headerHighlightImageSize, headerHighlightImageSize); + params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); + iv.setLayoutParams(params); + iv.setScaleType(ImageView.ScaleType.CENTER_CROP); + + row.removeViewAt(physicalIdx); + outer.addView(iv); + row.addView(outer, physicalIdx); + + if (headerHighlightImage != null) { + iv.setImageDrawable(headerHighlightImage); + } + } + } + + private void setStickerColor() { + int size = stickers.size(); + int[] orders = new int[size]; + int i = 0; + for (int key : stickers.keySet()) { + orders[i++] = key; + } + Arrays.sort(orders); + + int colorSize = stickerColors.length; + + for (i = 0; i < size; i++) { + for (TextView v : stickers.get(orders[i]).getView()) { + v.setBackgroundColor(Color.parseColor(stickerColors[i % (colorSize)])); + } + } + + } + + private void createTable() { + createTableHeader(); + for (int i = 0; i < rowCount; i++) { + TableRow tableRow = new TableRow(context); + tableRow.setLayoutParams(createTableLayoutParam()); + // Force LTR so Android doesn't mirror our physically-ordered RTL children + ViewCompat.setLayoutDirection(tableRow, ViewCompat.LAYOUT_DIRECTION_LTR); + + if (isRTL) { + // RTL: physically add day columns first (Day N-1 down to Day 0, left to right), + // then add Time column last so it appears on the far right. + for (int k = columnCount - 2; k >= 0; k--) { + // k is the day index (0 = first day e.g. Sunday) + TextView tv = new TextView(context); + tv.setLayoutParams(createTableRowParam(cellHeight)); + tv.setText(""); + Resources res = getResources(); + tv.setBackground(ResourcesCompat.getDrawable(res, R.drawable.item_border, null)); + Drawable background = tv.getBackground(); + if (background instanceof ShapeDrawable) { + ((ShapeDrawable) background).getPaint().setColor(colorSurface); + } else if (background instanceof GradientDrawable) { + ((GradientDrawable) background).setColor(colorSurface); + ((GradientDrawable) background).setStroke(borderWidth, colorBorders); + } else if (background instanceof ColorDrawable) { + ((ColorDrawable) background).setColor(colorSurface); + } + tv.setGravity(Gravity.CENTER); + tableRow.addView(tv); + } + // Add Time column last → it renders on the far right + TextView timeCell = new TextView(context); + timeCell.setLayoutParams(createTableRowParam(sideCellWidth, cellHeight)); + timeCell.setTextColor(sideColorText); + timeCell.setText(getHeaderTime(i)); + timeCell.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_SIDE_HEADER_FONT_SIZE_DP); + timeCell.setBackgroundColor(sideColor); + timeCell.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL); + tableRow.addView(timeCell); + } else { + // LTR: Time column first (left), then day columns + TextView timeCell = new TextView(context); + timeCell.setLayoutParams(createTableRowParam(sideCellWidth, cellHeight)); + timeCell.setTextColor(sideColorText); + timeCell.setText(getHeaderTime(i)); + timeCell.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_SIDE_HEADER_FONT_SIZE_DP); + timeCell.setBackgroundColor(sideColor); + timeCell.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL); + tableRow.addView(timeCell); + + for (int k = 1; k < columnCount; k++) { + TextView tv = new TextView(context); + tv.setLayoutParams(createTableRowParam(cellHeight)); + tv.setText(""); + Resources res = getResources(); + tv.setBackground(ResourcesCompat.getDrawable(res, R.drawable.item_border, null)); + Drawable background = tv.getBackground(); + if (background instanceof ShapeDrawable) { + ((ShapeDrawable) background).getPaint().setColor(colorSurface); + } else if (background instanceof GradientDrawable) { + ((GradientDrawable) background).setColor(colorSurface); + ((GradientDrawable) background).setStroke(borderWidth, colorBorders); + } else if (background instanceof ColorDrawable) { + ((ColorDrawable) background).setColor(colorSurface); + } + tv.setGravity(Gravity.CENTER); + tableRow.addView(tv); + } + } + tableBox.addView(tableRow); + } + } + + private void createTableHeader() { + TableRow tableRow = new TableRow(context); + tableRow.setLayoutParams(createTableLayoutParam()); + // Force LTR so Android doesn't mirror our physically-ordered RTL header children + ViewCompat.setLayoutDirection(tableRow, ViewCompat.LAYOUT_DIRECTION_LTR); + + if (isRTL) { + // RTL: physically add day headers from last day to first (left-to-right visually), + // then add the blank time header last so it appears on the far right. + // headerTitle[0] = blank side header, headerTitle[1..N] = day names + int dayCount = columnCount - 1; // number of day columns + for (int d = dayCount; d >= 1; d--) { + // d goes from last day down to first day + // In RTL, physical left = last day, physical right = first day (before time col) + TextView tv = new TextView(context); + tv.setLayoutParams(createTableRowParam(cellHeight)); + tv.setTextColor(sideAndHeaderTextColor); + tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEADER_FONT_SIZE_DP); + tv.setText(headerTitle[d]); + tv.setGravity(Gravity.CENTER); + tableRow.addView(tv); + } + // Time/side header last → far right + TextView sideHeader = new TextView(context); + sideHeader.setLayoutParams(createTableRowParam(sideCellWidth, cellHeight)); + sideHeader.setTextColor(sideAndHeaderTextColor); + sideHeader.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEADER_FONT_SIZE_DP); + sideHeader.setText(headerTitle[0]); + sideHeader.setGravity(Gravity.CENTER); + tableRow.addView(sideHeader); + } else { + // LTR: side header first (left), then day headers left to right + for (int i = 0; i < columnCount; i++) { + TextView tv = new TextView(context); + if (i == 0) { + tv.setLayoutParams(createTableRowParam(sideCellWidth, cellHeight)); + } else { + tv.setLayoutParams(createTableRowParam(cellHeight)); + } + tv.setTextColor(sideAndHeaderTextColor); + tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEADER_FONT_SIZE_DP); + tv.setText(headerTitle[i]); + tv.setGravity(Gravity.CENTER); + tableRow.addView(tv); + } + } + tableHeader.addView(tableRow); + } + + private RelativeLayout.LayoutParams createStickerParam(Schedule schedule) { + int cell_w = calCellWidth(); + int topMargin = calStickerTopPxByTime(schedule.getStartTime()); + + RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(cell_w, calStickerHeightPx(schedule)); + param.addRule(RelativeLayout.ALIGN_PARENT_TOP); + + // Always use ALIGN_PARENT_LEFT with absolute left margin. + // In both LTR and RTL, the physical column order is managed manually, + // so we can always anchor from the left edge unambiguously. + param.addRule(RelativeLayout.ALIGN_PARENT_LEFT); + int leftMargin; + if (isRTL) { + // RTL physical layout (left→right): [DayN-1][DayN-2]...[Day1][Day0][Time] + // Day d starts at (dayCount-1-d)*cell_w from left edge (no side column on left). + int dayCount = columnCount - 1; + leftMargin = (dayCount - 1 - schedule.getDay()) * cell_w; + } else { + // LTR: Time column is at left (width=sideCellWidth), then Day0, Day1 ... + leftMargin = sideCellWidth + cell_w * schedule.getDay(); + } + param.setMargins(leftMargin, topMargin, 0, 0); + + return param; + } + + private int calCellWidth() { + // Prefer stickerBox width since stickers are positioned inside it. + // This avoids any padding/scrollbar discrepancy with TimetableView.getWidth(). + int boxWidth = (stickerBox != null) ? stickerBox.getWidth() : 0; + if (boxWidth > 0) { + return (boxWidth - sideCellWidth) / (columnCount - 1); + } + // Fallback: view not yet measured — use TimetableView width + int viewWidth = getWidth(); + if (viewWidth <= 0) { + Display display = ((AppCompatActivity) context).getWindowManager().getDefaultDisplay(); + Point size = new Point(); + display.getSize(size); + viewWidth = size.x; + } + return (viewWidth - getPaddingLeft() - getPaddingRight() - sideCellWidth) / (columnCount - 1); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + if (w != oldw && w > 0) { + repositionStickers(); + } + } + + private void repositionStickers() { + for (int key : stickers.keySet()) { + Sticker sticker = stickers.get(key); + ArrayList views = sticker.getView(); + ArrayList schedules = sticker.getSchedules(); + for (int i = 0; i < views.size() && i < schedules.size(); i++) { + TextView tv = views.get(i); + Schedule schedule = schedules.get(i); + tv.setLayoutParams(createStickerParam(schedule)); + } + } + } + + private int calStickerHeightPx(Schedule schedule) { + int startTopPx = calStickerTopPxByTime(schedule.getStartTime()); + int endTopPx = calStickerTopPxByTime(schedule.getEndTime()); + int d = endTopPx - startTopPx; + + return d; + } + + private int calStickerTopPxByTime(Time time) { + int topPx = (time.getHour() - startTime) * cellHeight + (int) ((time.getMinute() / 60.0f) * cellHeight); + return topPx; + } + + private TableLayout.LayoutParams createTableLayoutParam() { + return new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT); + } + + private TableRow.LayoutParams createTableRowParam(int h_px) { + return new TableRow.LayoutParams(calCellWidth(), h_px); + } + + private TableRow.LayoutParams createTableRowParam(int w_px, int h_px) { + return new TableRow.LayoutParams(w_px, h_px); + } + + private String getHeaderTime(int i) { + int p = (startTime + i) % 24; + int res = p <= 12 ? p : p - 12; + String amStr = context.getString(R.string.am); + String pmStr = context.getString(R.string.pm); + if (p >= 0 && p < 12) { + return res + "\n" + amStr; + } else { + return res + "\n" + pmStr; + } + } + + static private int dp2Px(int dp) { + return (int) (dp * Resources.getSystem().getDisplayMetrics().density); + } + + private void onCreateByBuilder(Builder builder) { + this.rowCount = builder.rowCount; + this.columnCount = builder.columnCount; + this.cellHeight = builder.cellHeight; + this.sideCellWidth = builder.sideCellWidth; + this.headerTitle = builder.headerTitle; + this.stickerColors = builder.stickerColors; + this.startTime = builder.startTime; + this.headerHighlightColor = builder.headerHighlightColor; + this.colorSurface = builder.colorSurface; + this.colorBorders = builder.colorBorders; + this.sideColorText = builder.sideColorText; + this.sideColor = builder.sideColor; + this.sideAndHeaderTextColor = builder.sideAndHeaderTextColor; + this.borderWidth = builder.borderWidth; + this.forceRTL = builder.forceRTL; + + init(); + } + + + public interface OnStickerSelectedListener { + void OnStickerSelected(int idx, ArrayList schedules); + } + + public interface OnStickerSelectedLongClickListener { + void OnStickerSelectedLongClick(int idx, ArrayList schedules); + } + + static class Builder { + private Context context; + private int rowCount; + private int columnCount; + private int cellHeight; + private int sideCellWidth; + private String[] headerTitle; + private String[] stickerColors; + private int startTime; + private int headerHighlightColor; + private int colorSurface; + private int colorBorders; + private int sideColorText; + private int sideColor; + private int sideAndHeaderTextColor; + private int borderWidth; + private Boolean forceRTL = null; + + public Builder(Context context) { + this.context = context; + rowCount = DEFAULT_ROW_COUNT; + columnCount = DEFAULT_COLUMN_COUNT; + cellHeight = dp2Px(DEFAULT_CELL_HEIGHT_DP); + sideCellWidth = dp2Px(DEFAULT_SIDE_CELL_WIDTH_DP); + headerTitle = context.getResources().getStringArray(R.array.default_header_title); + stickerColors = context.getResources().getStringArray(R.array.default_sticker_color); + startTime = DEFAULT_START_TIME; + headerHighlightColor = context.getResources().getColor(R.color.default_header_highlight_color); + colorSurface = context.getResources().getColor(R.color.default_color_surface); + colorBorders = context.getResources().getColor(R.color.colorBorders); + sideColorText = context.getResources().getColor(R.color.default_color_side_text); + sideColor = context.getResources().getColor(R.color.colorSideHeader); + sideAndHeaderTextColor = context.getResources().getColor(R.color.default_color_side_header_text); + borderWidth = BorderWidth.NORMAL.ordinal(); + } + + public Builder setRowCount(int n) { + this.rowCount = n; + return this; + } + + public Builder setColumnCount(int n) { + this.columnCount = n; + return this; + } + + public Builder setCellHeight(int dp) { + this.cellHeight = dp2Px(dp); + return this; + } + + public Builder setSideCellWidth(int dp) { + this.sideCellWidth = dp2Px(dp); + return this; + } + + public Builder setHeaderTitle(String[] titles) { + this.headerTitle = titles; + return this; + } + + public Builder setStickerColors(String[] colors) { + this.stickerColors = colors; + return this; + } + + public Builder setStartTime(int t) { + this.startTime = t; + return this; + } + + public Builder setHeaderHighlightColor(int c) { + this.headerHighlightColor = c; + return this; + } + + public Builder setColorSurface(int c) { + this.colorSurface = c; + return this; + } + + public Builder setColorBorders(int c) { + this.colorBorders = c; + return this; + } + + public Builder setColorText(int c) { + this.sideColorText = c; + return this; + } + + public Builder setSideColorText(int c) { + this.sideColor = c; + return this; + } + + public Builder setSideAndHeaderTextColor(int c) { + this.sideAndHeaderTextColor = c; + return this; + } + + public Builder setBorderWidth(int b) { + this.borderWidth = b; + return this; + } + + public Builder setForceRTL(Boolean rtl) { + this.forceRTL = rtl; + return this; + } + + public TimetableView build() { + TimetableView timetableView = new TimetableView(context); + timetableView.onCreateByBuilder(this); + return timetableView; + } + } +} diff --git a/timetableview/src/main/java/com/github/tlaabs/timetableview/TimetableView.java b/timetableview/src/main/java/com/github/tlaabs/timetableview/TimetableView.java deleted file mode 100644 index 8f1644f..0000000 --- a/timetableview/src/main/java/com/github/tlaabs/timetableview/TimetableView.java +++ /dev/null @@ -1,462 +0,0 @@ -package com.github.tlaabs.timetableview; - -import android.app.Activity; -import android.content.Context; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.graphics.Point; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.support.v7.content.res.AppCompatResources; -import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.view.Display; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; - -public class TimetableView extends LinearLayout { - private static final int DEFAULT_ROW_COUNT = 12; - private static final int DEFAULT_COLUMN_COUNT = 6; - private static final int DEFAULT_CELL_HEIGHT_DP = 50; - private static final int DEFAULT_SIDE_CELL_WIDTH_DP = 30; - private static final int DEFAULT_START_TIME = 9; - - private static final int DEFAULT_SIDE_HEADER_FONT_SIZE_DP = 13; - private static final int DEFAULT_HEADER_FONT_SIZE_DP = 15; - private static final int DEFAULT_HEADER_HIGHLIGHT_FONT_SIZE_DP = 15; - private static final int DEFAULT_STICKER_FONT_SIZE_DP = 13; - - - private int rowCount; - private int columnCount; - private int cellHeight; - private int sideCellWidth; - private String[] headerTitle; - private String[] stickerColors; - private int startTime; - private int headerHighlightColor; - - private RelativeLayout stickerBox; - TableLayout tableHeader; - TableLayout tableBox; - - private Context context; - - HashMap stickers = new HashMap(); - private int stickerCount = -1; - - private OnStickerSelectedListener stickerSelectedListener = null; - - private HighlightMode highlightMode = HighlightMode.COLOR; - private int headerHighlightImageSize; - private Drawable headerHighlightImage = null; - - public TimetableView(Context context) { - super(context, null); - this.context = context; - } - - public TimetableView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public TimetableView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - this.context = context; - getAttrs(attrs); - init(); - } - - private void getAttrs(AttributeSet attrs) { - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TimetableView); - rowCount = a.getInt(R.styleable.TimetableView_row_count, DEFAULT_ROW_COUNT) - 1; - columnCount = a.getInt(R.styleable.TimetableView_column_count, DEFAULT_COLUMN_COUNT); - cellHeight = a.getDimensionPixelSize(R.styleable.TimetableView_cell_height, dp2Px(DEFAULT_CELL_HEIGHT_DP)); - sideCellWidth = a.getDimensionPixelSize(R.styleable.TimetableView_side_cell_width, dp2Px(DEFAULT_SIDE_CELL_WIDTH_DP)); - int titlesId = a.getResourceId(R.styleable.TimetableView_header_title, R.array.default_header_title); - headerTitle = a.getResources().getStringArray(titlesId); - int colorsId = a.getResourceId(R.styleable.TimetableView_sticker_colors, R.array.default_sticker_color); - stickerColors = a.getResources().getStringArray(colorsId); - startTime = a.getInt(R.styleable.TimetableView_start_time, DEFAULT_START_TIME); - headerHighlightColor = a.getColor(R.styleable.TimetableView_header_highlight_color, getResources().getColor(R.color.default_header_highlight_color)); - int highlightTypeValue = a.getInteger(R.styleable.TimetableView_header_highlight_type,0); - if(highlightTypeValue == 0) highlightMode = HighlightMode.COLOR; - else if(highlightTypeValue == 1) highlightMode = HighlightMode.IMAGE; - headerHighlightImageSize = a.getDimensionPixelSize(R.styleable.TimetableView_header_highlight_image_size, dp2Px(24)); - headerHighlightImage = a.getDrawable(R.styleable.TimetableView_header_highlight_image); - a.recycle(); - } - - private void init() { - LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View view = layoutInflater.inflate(R.layout.view_timetable, this, false); - addView(view); - - stickerBox = view.findViewById(R.id.sticker_box); - tableHeader = view.findViewById(R.id.table_header); - tableBox = view.findViewById(R.id.table_box); - - createTable(); - } - - public void setOnStickerSelectEventListener(OnStickerSelectedListener listener) { - stickerSelectedListener = listener; - } - - /** - * date : 2019-02-08 - * get all schedules TimetableView has. - */ - public ArrayList getAllSchedulesInStickers() { - ArrayList allSchedules = new ArrayList(); - for (int key : stickers.keySet()) { - for (Schedule schedule : stickers.get(key).getSchedules()) { - allSchedules.add(schedule); - } - } - return allSchedules; - } - - /** - * date : 2019-02-08 - * Used in Edit mode, To check a invalidate schedule. - */ - public ArrayList getAllSchedulesInStickersExceptIdx(int idx) { - ArrayList allSchedules = new ArrayList(); - for (int key : stickers.keySet()) { - if (idx == key) continue; - for (Schedule schedule : stickers.get(key).getSchedules()) { - allSchedules.add(schedule); - } - } - return allSchedules; - } - - public void add(ArrayList schedules) { - add(schedules, -1); - } - - private void add(final ArrayList schedules, int specIdx) { - final int count = specIdx < 0 ? ++stickerCount : specIdx; - Sticker sticker = new Sticker(); - for (Schedule schedule : schedules) { - TextView tv = new TextView(context); - - RelativeLayout.LayoutParams param = createStickerParam(schedule); - tv.setLayoutParams(param); - tv.setPadding(10, 0, 10, 0); - tv.setText(schedule.getClassTitle() + "\n" + schedule.getClassPlace()); - tv.setTextColor(Color.parseColor("#FFFFFF")); - tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_STICKER_FONT_SIZE_DP); - tv.setTypeface(null, Typeface.BOLD); - - tv.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if(stickerSelectedListener != null) - stickerSelectedListener.OnStickerSelected(count, schedules); - } - }); - - sticker.addTextView(tv); - sticker.addSchedule(schedule); - stickers.put(count, sticker); - stickerBox.addView(tv); - } - setStickerColor(); - } - - public String createSaveData() { - return SaveManager.saveSticker(stickers); - } - - public void load(String data) { - removeAll(); - stickers = SaveManager.loadSticker(data); - int maxKey = 0; - for (int key : stickers.keySet()) { - ArrayList schedules = stickers.get(key).getSchedules(); - add(schedules, key); - if (maxKey < key) maxKey = key; - } - stickerCount = maxKey + 1; - setStickerColor(); - } - - public void removeAll() { - for (int key : stickers.keySet()) { - Sticker sticker = stickers.get(key); - for (TextView tv : sticker.getView()) { - stickerBox.removeView(tv); - } - } - stickers.clear(); - } - - public void edit(int idx, ArrayList schedules) { - remove(idx); - add(schedules, idx); - } - - public void remove(int idx) { - Sticker sticker = stickers.get(idx); - for (TextView tv : sticker.getView()) { - stickerBox.removeView(tv); - } - stickers.remove(idx); - setStickerColor(); - } - - public void setHeaderHighlight(int idx) { - if(idx < 0)return; - TableRow row = (TableRow) tableHeader.getChildAt(0); - View element = row.getChildAt(idx); - if(highlightMode == HighlightMode.COLOR) { - TextView tx = (TextView)element; - tx.setTextColor(Color.parseColor("#FFFFFF")); - tx.setBackgroundColor(headerHighlightColor); - tx.setTypeface(null, Typeface.BOLD); - tx.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEADER_HIGHLIGHT_FONT_SIZE_DP); - } - else if(highlightMode == HighlightMode.IMAGE){ - RelativeLayout outer = new RelativeLayout(context); - outer.setLayoutParams(createTableRowParam(cellHeight)); - ImageView iv = new ImageView(context); - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(headerHighlightImageSize,headerHighlightImageSize); - params.addRule(RelativeLayout.CENTER_IN_PARENT,RelativeLayout.TRUE); - iv.setLayoutParams(params); - iv.setScaleType(ImageView.ScaleType.CENTER_CROP); - - row.removeViewAt(idx); - outer.addView(iv); - row.addView(outer,idx); - - if(headerHighlightImage != null) { - iv.setImageDrawable(headerHighlightImage); - } - - } - } - - private void setStickerColor() { - int size = stickers.size(); - int[] orders = new int[size]; - int i = 0; - for (int key : stickers.keySet()) { - orders[i++] = key; - } - Arrays.sort(orders); - - int colorSize = stickerColors.length; - - for (i = 0; i < size; i++) { - for (TextView v : stickers.get(orders[i]).getView()) { - v.setBackgroundColor(Color.parseColor(stickerColors[i % (colorSize)])); - } - } - - } - - private void createTable() { - createTableHeader(); - for (int i = 0; i < rowCount; i++) { - TableRow tableRow = new TableRow(context); - tableRow.setLayoutParams(createTableLayoutParam()); - - for (int k = 0; k < columnCount; k++) { - TextView tv = new TextView(context); - tv.setLayoutParams(createTableRowParam(cellHeight)); - if (k == 0) { - tv.setText(getHeaderTime(i)); - tv.setTextColor(getResources().getColor(R.color.colorHeaderText)); - tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_SIDE_HEADER_FONT_SIZE_DP); - tv.setBackgroundColor(getResources().getColor(R.color.colorHeader)); - tv.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL); - tv.setLayoutParams(createTableRowParam(sideCellWidth, cellHeight)); - } else { - tv.setText(""); - tv.setBackground(getResources().getDrawable(R.drawable.item_border)); - tv.setGravity(Gravity.RIGHT); - } - tableRow.addView(tv); - } - tableBox.addView(tableRow); - } - } - - private void createTableHeader() { - TableRow tableRow = new TableRow(context); - tableRow.setLayoutParams(createTableLayoutParam()); - - for (int i = 0; i < columnCount; i++) { - TextView tv = new TextView(context); - if (i == 0) { - tv.setLayoutParams(createTableRowParam(sideCellWidth, cellHeight)); - } else { - tv.setLayoutParams(createTableRowParam(cellHeight)); - } - tv.setTextColor(getResources().getColor(R.color.colorHeaderText)); - tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEADER_FONT_SIZE_DP); - tv.setText(headerTitle[i]); - tv.setGravity(Gravity.CENTER); - - tableRow.addView(tv); - } - tableHeader.addView(tableRow); - } - - private RelativeLayout.LayoutParams createStickerParam(Schedule schedule) { - int cell_w = calCellWidth(); - - RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(cell_w, calStickerHeightPx(schedule)); - param.addRule(RelativeLayout.ALIGN_PARENT_TOP); - param.addRule(RelativeLayout.ALIGN_PARENT_LEFT); - param.setMargins(sideCellWidth + cell_w * schedule.getDay(), calStickerTopPxByTime(schedule.getStartTime()), 0, 0); - - return param; - } - - private int calCellWidth(){ - Display display = ((Activity) context).getWindowManager().getDefaultDisplay(); - Point size = new Point(); - display.getSize(size); - int cell_w = (size.x-getPaddingLeft() - getPaddingRight()- sideCellWidth) / (columnCount - 1); - return cell_w; - } - - private int calStickerHeightPx(Schedule schedule) { - int startTopPx = calStickerTopPxByTime(schedule.getStartTime()); - int endTopPx = calStickerTopPxByTime(schedule.getEndTime()); - int d = endTopPx - startTopPx; - - return d; - } - - private int calStickerTopPxByTime(Time time) { - int topPx = (time.getHour() - startTime) * cellHeight + (int) ((time.getMinute() / 60.0f) * cellHeight); - return topPx; - } - - private TableLayout.LayoutParams createTableLayoutParam() { - return new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT); - } - - private TableRow.LayoutParams createTableRowParam(int h_px) { - return new TableRow.LayoutParams(calCellWidth(), h_px); - } - - private TableRow.LayoutParams createTableRowParam(int w_px, int h_px) { - return new TableRow.LayoutParams(w_px, h_px); - } - - private String getHeaderTime(int i) { - int p = (startTime + i) % 24; - int res = p <= 12 ? p : p - 12; - return res + ""; - } - - static private int dp2Px(int dp) { - return (int) (dp * Resources.getSystem().getDisplayMetrics().density); - } - - private void onCreateByBuilder(Builder builder) { - this.rowCount = builder.rowCount; - this.columnCount = builder.columnCount; - this.cellHeight = builder.cellHeight; - this.sideCellWidth = builder.sideCellWidth; - this.headerTitle = builder.headerTitle; - this.stickerColors = builder.stickerColors; - this.startTime = builder.startTime; - this.headerHighlightColor = builder.headerHighlightColor; - - init(); - } - - - public interface OnStickerSelectedListener { - void OnStickerSelected(int idx, ArrayList schedules); - } - - static class Builder { - private Context context; - private int rowCount; - private int columnCount; - private int cellHeight; - private int sideCellWidth; - private String[] headerTitle; - private String[] stickerColors; - private int startTime; - private int headerHighlightColor; - - public Builder(Context context) { - this.context = context; - rowCount = DEFAULT_ROW_COUNT; - columnCount = DEFAULT_COLUMN_COUNT; - cellHeight = dp2Px(DEFAULT_CELL_HEIGHT_DP); - sideCellWidth = dp2Px(DEFAULT_SIDE_CELL_WIDTH_DP); - headerTitle = context.getResources().getStringArray(R.array.default_header_title); - stickerColors = context.getResources().getStringArray(R.array.default_sticker_color); - startTime = DEFAULT_START_TIME; - headerHighlightColor = context.getResources().getColor(R.color.default_header_highlight_color); - } - - public Builder setRowCount(int n) { - this.rowCount = n; - return this; - } - - public Builder setColumnCount(int n) { - this.columnCount = n; - return this; - } - - public Builder setCellHeight(int dp) { - this.cellHeight = dp2Px(dp); - return this; - } - - public Builder setSideCellWidth(int dp) { - this.sideCellWidth = dp2Px(dp); - return this; - } - - public Builder setHeaderTitle(String[] titles) { - this.headerTitle = titles; - return this; - } - - public Builder setStickerColors(String[] colors) { - this.stickerColors = colors; - return this; - } - - public Builder setStartTime(int t) { - this.startTime = t; - return this; - } - - public Builder setHeaderHighlightColor(int c) { - this.headerHighlightColor = c; - return this; - } - - public TimetableView build() { - TimetableView timetableView = new TimetableView(context); - timetableView.onCreateByBuilder(this); - return timetableView; - } - } -} diff --git a/timetableview/src/main/res/drawable/item_border.xml b/timetableview/src/main/res/drawable/item_border.xml index de89ee8..c7a9ca4 100644 --- a/timetableview/src/main/res/drawable/item_border.xml +++ b/timetableview/src/main/res/drawable/item_border.xml @@ -1,7 +1,7 @@ - + + android:color="@color/colorBorders" /> \ No newline at end of file diff --git a/timetableview/src/main/res/layout/table_header.xml b/timetableview/src/main/res/layout/table_header.xml index faf08c4..d282a87 100644 --- a/timetableview/src/main/res/layout/table_header.xml +++ b/timetableview/src/main/res/layout/table_header.xml @@ -1,9 +1,9 @@ + - + /> \ No newline at end of file diff --git a/timetableview/src/main/res/layout/view_timetable.xml b/timetableview/src/main/res/layout/view_timetable.xml index a7ec1a4..1254e9c 100644 --- a/timetableview/src/main/res/layout/view_timetable.xml +++ b/timetableview/src/main/res/layout/view_timetable.xml @@ -1,24 +1,23 @@ - - + android:orientation="vertical"> + + + android:layout_weight="1"> - + diff --git a/timetableview/src/main/res/values-ar/strings.xml b/timetableview/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..25cbf52 --- /dev/null +++ b/timetableview/src/main/res/values-ar/strings.xml @@ -0,0 +1,13 @@ + + + + + الأحد + الإثنين + الثلاثاء + الأربعاء + الخميس + + ص + م + diff --git a/timetableview/src/main/res/values/attrs_timetable.xml b/timetableview/src/main/res/values/attrs_timetable.xml index 9260988..5577f08 100644 --- a/timetableview/src/main/res/values/attrs_timetable.xml +++ b/timetableview/src/main/res/values/attrs_timetable.xml @@ -1,19 +1,32 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - + + - - + + + \ No newline at end of file diff --git a/timetableview/src/main/res/values/colors.xml b/timetableview/src/main/res/values/colors.xml index 19c69f5..4d0b4e1 100644 --- a/timetableview/src/main/res/values/colors.xml +++ b/timetableview/src/main/res/values/colors.xml @@ -1,8 +1,9 @@ - #fcfcfc - #7d7d7d - #efefef + #ffffff + #D9000000 + @color/default_color_side_header_text + #F5F5F5 #f08676 @@ -16,9 +17,6 @@ #d397ed - #7d7d7d - #7d7d7d - #ffffff #74a4f3 - #ffffff + #ffffff diff --git a/timetableview/src/main/res/values/strings.xml b/timetableview/src/main/res/values/strings.xml index 00b568b..ccc3a0d 100644 --- a/timetableview/src/main/res/values/strings.xml +++ b/timetableview/src/main/res/values/strings.xml @@ -7,4 +7,6 @@ Thu Fri + AM + PM diff --git a/timetableview/src/test/java/com/github/tlaabs/timetableview/ExampleUnitTest.java b/timetableview/src/test/java/com/github/omarb1989/timetableview/ExampleUnitTest.java similarity index 88% rename from timetableview/src/test/java/com/github/tlaabs/timetableview/ExampleUnitTest.java rename to timetableview/src/test/java/com/github/omarb1989/timetableview/ExampleUnitTest.java index f3b41e4..2b3559c 100644 --- a/timetableview/src/test/java/com/github/tlaabs/timetableview/ExampleUnitTest.java +++ b/timetableview/src/test/java/com/github/omarb1989/timetableview/ExampleUnitTest.java @@ -1,4 +1,4 @@ -package com.github.tlaabs.timetableview; +package com.github.omarb1989.timetableview; import org.junit.Test;