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
[](https://opensource.org/licenses/Apache-2.0)
[](https://android-arsenal.com/api?level=19)
-[](https://jitpack.io/#tlaabs/TimetableView)
+[](https://jitpack.io/#omarb1989/TimetableView)
Android Library that creates simple time table.
+
+
-
-
## 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;