(TAG);
+ }
+
+ @Override
+ public URI getRequestURI() {
+ return this.requestURI;
+ }
+
+ @Override
+ public void setRequestURI(URI requestURI) {
+ this.requestURI = requestURI;
+ }
+
+ @Override
+ public Header[] getRequestHeaders() {
+ return this.requestHeaders;
+ }
+
+ @Override
+ public void setRequestHeaders(Header[] requestHeaders) {
+ this.requestHeaders = requestHeaders;
+ }
+
+ @Override
+ public boolean getUseSynchronousMode() {
+ return useSynchronousMode;
+ }
+
+ @Override
+ public void setUseSynchronousMode(boolean sync) {
+ // A looper must be prepared before setting asynchronous mode.
+ if (!sync && looper == null) {
+ sync = true;
+ AsyncHttpClient.log.w(LOG_TAG, "Current thread has not called Looper.prepare(). Forcing synchronous mode.");
+ }
+
+ // If using asynchronous mode.
+ if (!sync && handler == null) {
+ // Create a handler on current thread to submit tasks
+ handler = new ResponderHandler(this, looper);
+ } else if (sync && handler != null) {
+ // TODO: Consider adding a flag to remove all queued messages.
+ handler = null;
+ }
+
+ useSynchronousMode = sync;
+ }
+
+ @Override
+ public boolean getUsePoolThread() {
+ return usePoolThread;
+ }
+
+ @Override
+ public void setUsePoolThread(boolean pool) {
+ // If pool thread is to be used, there's no point in keeping a reference
+ // to the looper and no need for a handler.
+ if (pool) {
+ looper = null;
+ handler = null;
+ }
+
+ usePoolThread = pool;
+ }
+
+ public String getCharset() {
+ return this.responseCharset == null ? DEFAULT_CHARSET : this.responseCharset;
+ }
+
+ /**
+ * Sets the charset for the response string. If not set, the default is UTF-8.
+ *
+ * @param charset to be used for the response string.
+ * @see Charset
+ */
+ public void setCharset(final String charset) {
+ this.responseCharset = charset;
+ }
+
+ /**
+ * Fired when the request progress, override to handle in your own code
+ *
+ * @param bytesWritten offset from start of file
+ * @param totalSize total size of file
+ */
+ public void onProgress(long bytesWritten, long totalSize) {
+ AsyncHttpClient.log.v(LOG_TAG, String.format(Locale.US, "Progress %d from %d (%2.0f%%)", bytesWritten, totalSize, (totalSize > 0) ? (bytesWritten * 1.0 / totalSize) * 100 : -1));
+ }
+
+ /**
+ * Fired when the request is started, override to handle in your own code
+ */
+ public void onStart() {
+ // default log warning is not necessary, because this method is just optional notification
+ }
+
+ /**
+ * Fired in all cases when the request is finished, after both success and failure, override to
+ * handle in your own code
+ */
+ public void onFinish() {
+ // default log warning is not necessary, because this method is just optional notification
+ }
+
+ @Override
+ public void onPreProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {
+ // default action is to do nothing...
+ }
+
+ @Override
+ public void onPostProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {
+ // default action is to do nothing...
+ }
+
+ /**
+ * Fired when a request returns successfully, override to handle in your own code
+ *
+ * @param statusCode the status code of the response
+ * @param headers return headers, if any
+ * @param responseBody the body of the HTTP response from the server
+ */
+ public abstract void onSuccess(int statusCode, Header[] headers, byte[] responseBody);
+
+ /**
+ * Fired when a request fails to complete, override to handle in your own code
+ *
+ * @param statusCode return HTTP status code
+ * @param headers return headers, if any
+ * @param responseBody the response body, if any
+ * @param error the underlying cause of the failure
+ */
+ public abstract void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error);
+
+ /**
+ * Fired when a retry occurs, override to handle in your own code
+ *
+ * @param retryNo number of retry
+ */
+ public void onRetry(int retryNo) {
+ AsyncHttpClient.log.d(LOG_TAG, String.format(Locale.US, "Request retry no. %d", retryNo));
+ }
+
+ public void onCancel() {
+ AsyncHttpClient.log.d(LOG_TAG, "Request got cancelled");
+ }
+
+ public void onUserException(Throwable error) {
+ AsyncHttpClient.log.e(LOG_TAG, "User-space exception detected!", error);
+ throw new RuntimeException(error);
+ }
+
+ @Override
+ final public void sendProgressMessage(long bytesWritten, long bytesTotal) {
+ sendMessage(obtainMessage(PROGRESS_MESSAGE, new Object[]{bytesWritten, bytesTotal}));
+ }
+
+ @Override
+ final public void sendSuccessMessage(int statusCode, Header[] headers, byte[] responseBytes) {
+ sendMessage(obtainMessage(SUCCESS_MESSAGE, new Object[]{statusCode, headers, responseBytes}));
+ }
+
+ @Override
+ final public void sendFailureMessage(int statusCode, Header[] headers, byte[] responseBody, Throwable throwable) {
+ sendMessage(obtainMessage(FAILURE_MESSAGE, new Object[]{statusCode, headers, responseBody, throwable}));
+ }
+
+ @Override
+ final public void sendStartMessage() {
+ sendMessage(obtainMessage(START_MESSAGE, null));
+ }
+
+ @Override
+ final public void sendFinishMessage() {
+ sendMessage(obtainMessage(FINISH_MESSAGE, null));
+ }
+
+ @Override
+ final public void sendRetryMessage(int retryNo) {
+ sendMessage(obtainMessage(RETRY_MESSAGE, new Object[]{retryNo}));
+ }
+
+ @Override
+ final public void sendCancelMessage() {
+ sendMessage(obtainMessage(CANCEL_MESSAGE, null));
+ }
+
+ // Methods which emulate android's Handler and Message methods
+ protected void handleMessage(InnerEvent message) {
+ Object[] response;
+
+ try {
+ switch (message.eventId) {
+ case SUCCESS_MESSAGE:
+ response = (Object[]) message.object;
+ if (response != null && response.length >= 3) {
+ onSuccess((Integer) response[0], (Header[]) response[1], (byte[]) response[2]);
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "SUCCESS_MESSAGE didn't got enough params");
+ }
+ break;
+ case FAILURE_MESSAGE:
+ response = (Object[]) message.object;
+ if (response != null && response.length >= 4) {
+ onFailure((Integer) response[0], (Header[]) response[1], (byte[]) response[2], (Throwable) response[3]);
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "FAILURE_MESSAGE didn't got enough params");
+ }
+ break;
+ case START_MESSAGE:
+ onStart();
+ break;
+ case FINISH_MESSAGE:
+ onFinish();
+ break;
+ case PROGRESS_MESSAGE:
+ response = (Object[]) message.object;
+ if (response != null && response.length >= 2) {
+ try {
+ onProgress((Long) response[0], (Long) response[1]);
+ } catch (Throwable t) {
+ AsyncHttpClient.log.e(LOG_TAG, "custom onProgress contains an error", t);
+ }
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "PROGRESS_MESSAGE didn't got enough params");
+ }
+ break;
+ case RETRY_MESSAGE:
+ response = (Object[]) message.object;
+ if (response != null && response.length == 1) {
+ onRetry((Integer) response[0]);
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "RETRY_MESSAGE didn't get enough params");
+ }
+ break;
+ case CANCEL_MESSAGE:
+ onCancel();
+ break;
+ }
+ } catch (Throwable error) {
+ onUserException(error);
+ }
+ }
+
+ protected void sendMessage(InnerEvent msg) {
+ if (getUseSynchronousMode() || handler == null) {
+ handleMessage(msg);
+ } else if (!Thread.currentThread().isInterrupted()) { // do not send messages if request has been cancelled
+ Utils.asserts(handler != null, "handler should not be null!");
+ AsyncHttpClient.log.d("loop","handler!= null"+looper.toString());
+ handler.sendEvent(msg);
+ //zel
+// looper.run();
+ }
+ }
+
+ /**
+ * Helper method to send runnable into local handler loop
+ *
+ * @param runnable runnable instance, can be null
+ */
+ protected void postRunnable(Runnable runnable) {
+ if (runnable != null) {
+ if (getUseSynchronousMode() || handler == null) {
+ // This response handler is synchronous, run on current thread
+ runnable.run();
+ } else {
+ // Otherwise, run on provided handler
+ handler.postTask(runnable);
+ //zel
+// looper.run();
+ }
+ }
+ }
+
+ /**
+ * Helper method to create Message instance from handler
+ *
+ * @param responseMessageId constant to identify Handler message
+ * @param responseMessageData object to be passed to message receiver
+ * @return Message instance, should not be null
+ */
+ protected InnerEvent obtainMessage(int responseMessageId, Object responseMessageData) {
+ InnerEvent event= InnerEvent.get(responseMessageId,responseMessageData);
+ //zel
+ return event;
+ }
+
+ @Override
+ public void sendResponseMessage(HttpResponse response) throws IOException {
+ // do not process if request has been cancelled
+ if (!Thread.currentThread().isInterrupted()) {
+ StatusLine status = response.getStatusLine();
+ byte[] responseBody;
+ responseBody = getResponseData(response.getEntity());
+ // additional cancellation check as getResponseData() can take non-zero time to process
+ if (!Thread.currentThread().isInterrupted()) {
+ if (status.getStatusCode() >= 300) {
+ sendFailureMessage(status.getStatusCode(), response.getAllHeaders(), responseBody, new HttpResponseException(status.getStatusCode(), status.getReasonPhrase()));
+ } else {
+ sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(), responseBody);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns byte array of response HttpEntity contents
+ *
+ * @param entity can be null
+ * @return response entity body or null
+ * @throws IOException if reading entity or creating byte array failed
+ */
+ byte[] getResponseData(HttpEntity entity) throws IOException {
+ byte[] responseBody = null;
+ if (entity != null) {
+ InputStream instream = entity.getContent();
+ if (instream != null) {
+ long contentLength = entity.getContentLength();
+ if (contentLength > Integer.MAX_VALUE) {
+ throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
+ }
+ int buffersize = (contentLength <= 0) ? BUFFER_SIZE : (int) contentLength;
+ try {
+ ByteArrayBuffer buffer = new ByteArrayBuffer(buffersize);
+ try {
+ byte[] tmp = new byte[BUFFER_SIZE];
+ long count = 0;
+ int l;
+ // do not send messages if request has been cancelled
+ while ((l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) {
+ count += l;
+ buffer.append(tmp, 0, l);
+ sendProgressMessage(count, (contentLength <= 0 ? 1 : contentLength));
+ }
+ } finally {
+ AsyncHttpClient.silentCloseInputStream(instream);
+ AsyncHttpClient.endEntityViaReflection(entity);
+ }
+ responseBody = buffer.toByteArray();
+ } catch (OutOfMemoryError e) {
+ System.gc();
+ throw new IOException("File too large to fit into available memory");
+ }
+ }
+ }
+ return responseBody;
+ }
+
+ /**
+ * Avoid leaks by using a non-anonymous handler class.
+ */
+ private static class ResponderHandler extends EventHandler {
+ private final AsyncHttpResponseHandler mResponder;
+
+ ResponderHandler(AsyncHttpResponseHandler mResponder, EventRunner looper) {
+ super(looper);
+ this.mResponder = mResponder;
+ }
+
+
+ @Override
+ protected void processEvent(InnerEvent event) {
+ super.processEvent(event);
+ mResponder.handleMessage(event);
+ }
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64.java
new file mode 100644
index 0000000000000000000000000000000000000000..82dfeaf72253dd4d622364a4c7ae476f9172c181
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64.java
@@ -0,0 +1,716 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.httplibrary.utils;
+
+import ohos.agp.render.render3d.BuildConfig;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Utilities for encoding and decoding the Base64 representation of binary data. See RFCs 2045 and 3548 .
+ */
+public class Base64 {
+ /**
+ * Default values for encoder/decoder flags.
+ */
+ public static final int DEFAULT = 0;
+
+ /**
+ * Encoder flag bit to omit the padding '=' characters at the end of the output (if any).
+ */
+ public static final int NO_PADDING = 1;
+
+ /**
+ * Encoder flag bit to omit all line terminators (i.e., the output will be on one long line).
+ */
+ public static final int NO_WRAP = 2;
+
+ /**
+ * Encoder flag bit to indicate lines should be terminated with a CRLF pair instead of just an
+ * LF. Has no effect if {@code NO_WRAP} is specified as well.
+ */
+ public static final int CRLF = 4;
+
+ /**
+ * Encoder/decoder flag bit to indicate using the "URL and filename safe" variant of Base64 (see
+ * RFC 3548 section 4) where {@code -} and {@code _} are used in place of {@code +} and {@code
+ * /}.
+ */
+ public static final int URL_SAFE = 8;
+
+ /**
+ * Flag to pass to {@link Base64OutputStream} to indicate that it should not close the output
+ * stream it is wrapping when it itself is closed.
+ */
+ public static final int NO_CLOSE = 16;
+
+ // --------------------------------------------------------
+ // shared code
+ // --------------------------------------------------------
+
+ private Base64() {
+ } // don't instantiate
+
+ // --------------------------------------------------------
+ // decoding
+ // --------------------------------------------------------
+
+ /**
+ * Decode the Base64-encoded data in input and return the data in a new byte array.
+ *
The padding '=' characters at the end are considered optional, but if any
+ * are present, there must be the correct number of them.
+ *
+ * @param str the input String to decode, which is converted to bytes using the default
+ * charset
+ * @param flags controls certain features of the decoded output. Pass {@code DEFAULT} to decode
+ * standard Base64.
+ * @return decoded bytes
+ * @throws IllegalArgumentException if the input contains incorrect padding
+ */
+ public static byte[] decode(String str, int flags) {
+ return decode(str.getBytes(), flags);
+ }
+
+ /**
+ * Decode the Base64-encoded data in input and return the data in a new byte array.
+ *
The padding '=' characters at the end are considered optional, but if any
+ * are present, there must be the correct number of them.
+ *
+ * @param input the input array to decode
+ * @param flags controls certain features of the decoded output. Pass {@code DEFAULT} to decode
+ * standard Base64.
+ * @return decoded bytes
+ * @throws IllegalArgumentException if the input contains incorrect padding
+ */
+ public static byte[] decode(byte[] input, int flags) {
+ return decode(input, 0, input.length, flags);
+ }
+
+ /**
+ * Decode the Base64-encoded data in input and return the data in a new byte array.
+ *
The padding '=' characters at the end are considered optional, but if any
+ * are present, there must be the correct number of them.
+ *
+ * @param input the data to decode
+ * @param offset the position within the input array at which to start
+ * @param len the number of bytes of input to decode
+ * @param flags controls certain features of the decoded output. Pass {@code DEFAULT} to decode
+ * standard Base64.
+ * @return decoded bytes for given offset and length
+ * @throws IllegalArgumentException if the input contains incorrect padding
+ */
+ public static byte[] decode(byte[] input, int offset, int len, int flags) {
+ // Allocate space for the most data the input could represent.
+ // (It could contain less if it contains whitespace, etc.)
+ Decoder decoder = new Decoder(flags, new byte[len * 3 / 4]);
+
+ if (!decoder.process(input, offset, len, true)) {
+ throw new IllegalArgumentException("bad base-64");
+ }
+
+ // Maybe we got lucky and allocated exactly enough output space.
+ if (decoder.op == decoder.output.length) {
+ return decoder.output;
+ }
+
+ // Need to shorten the array, so allocate a new one of the
+ // right size and copy.
+ byte[] temp = new byte[decoder.op];
+ System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
+ return temp;
+ }
+
+ /**
+ * Base64-encode the given data and return a newly allocated String with the result.
+ *
+ * @param input the data to encode
+ * @param flags controls certain features of the encoded output. Passing {@code DEFAULT} results
+ * in output that adheres to RFC 2045.
+ * @return base64 string containing encoded input
+ */
+ public static String encodeToString(byte[] input, int flags) {
+ try {
+ return new String(encode(input, flags), "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ // US-ASCII is guaranteed to be available.
+ throw new AssertionError(e);
+ }
+ }
+
+ // --------------------------------------------------------
+ // encoding
+ // --------------------------------------------------------
+
+ /**
+ * Base64-encode the given data and return a newly allocated String with the result.
+ *
+ * @param input the data to encode
+ * @param offset the position within the input array at which to start
+ * @param len the number of bytes of input to encode
+ * @param flags controls certain features of the encoded output. Passing {@code DEFAULT}
+ * results in output that adheres to RFC 2045.
+ * @return base64 string containing encoded range of input
+ */
+ public static String encodeToString(byte[] input, int offset, int len, int flags) {
+ try {
+ return new String(encode(input, offset, len, flags), "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ // US-ASCII is guaranteed to be available.
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Base64-encode the given data and return a newly allocated byte[] with the result.
+ *
+ * @param input the data to encode
+ * @param flags controls certain features of the encoded output. Passing {@code DEFAULT} results
+ * in output that adheres to RFC 2045.
+ * @return base64 encoded input as bytes
+ */
+ public static byte[] encode(byte[] input, int flags) {
+ return encode(input, 0, input.length, flags);
+ }
+
+ /**
+ * Base64-encode the given data and return a newly allocated byte[] with the result.
+ *
+ * @param input the data to encode
+ * @param offset the position within the input array at which to start
+ * @param len the number of bytes of input to encode
+ * @param flags controls certain features of the encoded output. Passing {@code DEFAULT}
+ * results in output that adheres to RFC 2045.
+ * @return base64 encoded input as bytes
+ */
+ public static byte[] encode(byte[] input, int offset, int len, int flags) {
+ Encoder encoder = new Encoder(flags, null);
+
+ // Compute the exact length of the array we will produce.
+ int output_len = len / 3 * 4;
+
+ // Account for the tail of the data and the padding bytes, if any.
+ if (encoder.do_padding) {
+ if (len % 3 > 0) {
+ output_len += 4;
+ }
+ } else {
+ switch (len % 3) {
+ case 0:
+ break;
+ case 1:
+ output_len += 2;
+ break;
+ case 2:
+ output_len += 3;
+ break;
+ }
+ }
+
+ // Account for the newlines, if any.
+ if (encoder.do_newline && len > 0) {
+ output_len += (((len - 1) / (3 * Encoder.LINE_GROUPS)) + 1) *
+ (encoder.do_cr ? 2 : 1);
+ }
+
+ encoder.output = new byte[output_len];
+ encoder.process(input, offset, len, true);
+
+ if (BuildConfig.DEBUG && encoder.op != output_len) {
+ throw new AssertionError();
+ }
+
+ return encoder.output;
+ }
+
+ /* package */ static abstract class Coder {
+ public byte[] output;
+ public int op;
+
+ /**
+ * Encode/decode another block of input data. this.output is provided by the caller, and
+ * must be big enough to hold all the coded data. On exit, this.opwill be set to the length
+ * of the coded data.
+ *
+ * @param finish true if this is the final call to process for this object. Will finalize
+ * the coder state and include any final bytes in the output.
+ * @return true if the input so far is good; false if some error has been detected in the
+ * input stream..
+ */
+ public abstract boolean process(byte[] input, int offset, int len, boolean finish);
+
+ /**
+ * @return the maximum number of bytes a call to process() could produce for the given
+ * number of input bytes. This may be an overestimate.
+ */
+ public abstract int maxOutputSize(int len);
+ }
+
+ /* package */ static class Decoder extends Coder {
+ /**
+ * Lookup table for turning bytes into their position in the Base64 alphabet.
+ */
+ private static final int DECODE[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+ /**
+ * Decode lookup table for the "web safe" variant (RFC 3548 sec. 4) where - and _ replace +
+ * and /.
+ */
+ private static final int DECODE_WEBSAFE[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+ /**
+ * Non-data values in the DECODE arrays.
+ */
+ private static final int SKIP = -1;
+ private static final int EQUALS = -2;
+ final private int[] alphabet;
+ /**
+ * States 0-3 are reading through the next input tuple. State 4 is having read one '=' and
+ * expecting exactly one more. State 5 is expecting no more data or padding characters in
+ * the input. State 6 is the error state; an error has been detected in the input and no
+ * future input can "fix" it.
+ */
+ private int state; // state number (0 to 6)
+ private int value;
+
+ public Decoder(int flags, byte[] output) {
+ this.output = output;
+
+ alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
+ state = 0;
+ value = 0;
+ }
+
+ /**
+ * @return an overestimate for the number of bytes {@code len} bytes could decode to.
+ */
+ public int maxOutputSize(int len) {
+ return len * 3 / 4 + 10;
+ }
+
+ /**
+ * Decode another block of input data.
+ *
+ * @return true if the state machine is still healthy. false if bad base-64 data has been
+ * detected in the input stream.
+ */
+ public boolean process(byte[] input, int offset, int len, boolean finish) {
+ if (this.state == 6) return false;
+
+ int p = offset;
+ len += offset;
+
+ // Using local variables makes the decoder about 12%
+ // faster than if we manipulate the member variables in
+ // the loop. (Even alphabet makes a measurable
+ // difference, which is somewhat surprising to me since
+ // the member variable is final.)
+ int state = this.state;
+ int value = this.value;
+ int op = 0;
+ final byte[] output = this.output;
+ final int[] alphabet = this.alphabet;
+
+ while (p < len) {
+ // Try the fast path: we're starting a new tuple and the
+ // next four bytes of the input stream are all data
+ // bytes. This corresponds to going through states
+ // 0-1-2-3-0. We expect to use this method for most of
+ // the data.
+ //
+ // If any of the next four bytes of input are non-data
+ // (whitespace, etc.), value will end up negative. (All
+ // the non-data values in decode are small negative
+ // numbers, so shifting any of them up and or'ing them
+ // together will result in a value with its top bit set.)
+ //
+ // You can remove this whole block and the output should
+ // be the same, just slower.
+ if (state == 0) {
+ while (p + 4 <= len &&
+ (value = ((alphabet[input[p] & 0xff] << 18) |
+ (alphabet[input[p + 1] & 0xff] << 12) |
+ (alphabet[input[p + 2] & 0xff] << 6) |
+ (alphabet[input[p + 3] & 0xff]))) >= 0) {
+ output[op + 2] = (byte) value;
+ output[op + 1] = (byte) (value >> 8);
+ output[op] = (byte) (value >> 16);
+ op += 3;
+ p += 4;
+ }
+ if (p >= len) break;
+ }
+
+ // The fast path isn't available -- either we've read a
+ // partial tuple, or the next four input bytes aren't all
+ // data, or whatever. Fall back to the slower state
+ // machine implementation.
+
+ int d = alphabet[input[p++] & 0xff];
+
+ switch (state) {
+ case 0:
+ if (d >= 0) {
+ value = d;
+ ++state;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 1:
+ if (d >= 0) {
+ value = (value << 6) | d;
+ ++state;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 2:
+ if (d >= 0) {
+ value = (value << 6) | d;
+ ++state;
+ } else if (d == EQUALS) {
+ // Emit the last (partial) output tuple;
+ // expect exactly one more padding character.
+ output[op++] = (byte) (value >> 4);
+ state = 4;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 3:
+ if (d >= 0) {
+ // Emit the output triple and return to state 0.
+ value = (value << 6) | d;
+ output[op + 2] = (byte) value;
+ output[op + 1] = (byte) (value >> 8);
+ output[op] = (byte) (value >> 16);
+ op += 3;
+ state = 0;
+ } else if (d == EQUALS) {
+ // Emit the last (partial) output tuple;
+ // expect no further data or padding characters.
+ output[op + 1] = (byte) (value >> 2);
+ output[op] = (byte) (value >> 10);
+ op += 2;
+ state = 5;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 4:
+ if (d == EQUALS) {
+ ++state;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 5:
+ if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+ }
+ }
+
+ if (!finish) {
+ // We're out of input, but a future call could provide
+ // more.
+ this.state = state;
+ this.value = value;
+ this.op = op;
+ return true;
+ }
+
+ // Done reading input. Now figure out where we are left in
+ // the state machine and finish up.
+
+ switch (state) {
+ case 0:
+ // Output length is a multiple of three. Fine.
+ break;
+ case 1:
+ // Read one extra input byte, which isn't enough to
+ // make another output byte. Illegal.
+ this.state = 6;
+ return false;
+ case 2:
+ // Read two extra input bytes, enough to emit 1 more
+ // output byte. Fine.
+ output[op++] = (byte) (value >> 4);
+ break;
+ case 3:
+ // Read three extra input bytes, enough to emit 2 more
+ // output bytes. Fine.
+ output[op++] = (byte) (value >> 10);
+ output[op++] = (byte) (value >> 2);
+ break;
+ case 4:
+ // Read one padding '=' when we expected 2. Illegal.
+ this.state = 6;
+ return false;
+ case 5:
+ // Read all the padding '='s we expected and no more.
+ // Fine.
+ break;
+ }
+
+ this.state = state;
+ this.op = op;
+ return true;
+ }
+ }
+
+ /* package */ static class Encoder extends Coder {
+ /**
+ * Emit a new line every this many output tuples. Corresponds to a 76-character line length
+ * (the maximum allowable according to RFC
+ * 2045 ).
+ */
+ public static final int LINE_GROUPS = 19;
+
+ /**
+ * Lookup table for turning Base64 alphabet positions (6 bits) into output bytes.
+ */
+ private static final byte ENCODE[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
+ };
+
+ /**
+ * Lookup table for turning Base64 alphabet positions (6 bits) into output bytes.
+ */
+ private static final byte ENCODE_WEBSAFE[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
+ };
+ final public boolean do_padding;
+ final public boolean do_newline;
+ final public boolean do_cr;
+ final private byte[] tail;
+ final private byte[] alphabet;
+ /* package */ int tailLen;
+ private int count;
+
+ public Encoder(int flags, byte[] output) {
+ this.output = output;
+
+ do_padding = (flags & NO_PADDING) == 0;
+ do_newline = (flags & NO_WRAP) == 0;
+ do_cr = (flags & CRLF) != 0;
+ alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
+
+ tail = new byte[2];
+ tailLen = 0;
+
+ count = do_newline ? LINE_GROUPS : -1;
+ }
+
+ /**
+ * @return an overestimate for the number of bytes {@code len} bytes could encode to.
+ */
+ public int maxOutputSize(int len) {
+ return len * 8 / 5 + 10;
+ }
+
+ public boolean process(byte[] input, int offset, int len, boolean finish) {
+ // Using local variables makes the encoder about 9% faster.
+ final byte[] alphabet = this.alphabet;
+ final byte[] output = this.output;
+ int op = 0;
+ int count = this.count;
+
+ int p = offset;
+ len += offset;
+ int v = -1;
+
+ // First we need to concatenate the tail of the previous call
+ // with any input bytes available now and see if we can empty
+ // the tail.
+
+ switch (tailLen) {
+ case 0:
+ // There was no tail.
+ break;
+
+ case 1:
+ if (p + 2 <= len) {
+ // A 1-byte tail with at least 2 bytes of
+ // input available now.
+ v = ((tail[0] & 0xff) << 16) |
+ ((input[p++] & 0xff) << 8) |
+ (input[p++] & 0xff);
+ tailLen = 0;
+ }
+ break;
+
+ case 2:
+ if (p + 1 <= len) {
+ // A 2-byte tail with at least 1 byte of input.
+ v = ((tail[0] & 0xff) << 16) |
+ ((tail[1] & 0xff) << 8) |
+ (input[p++] & 0xff);
+ tailLen = 0;
+ }
+ break;
+ }
+
+ if (v != -1) {
+ output[op++] = alphabet[(v >> 18) & 0x3f];
+ output[op++] = alphabet[(v >> 12) & 0x3f];
+ output[op++] = alphabet[(v >> 6) & 0x3f];
+ output[op++] = alphabet[v & 0x3f];
+ if (--count == 0) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ count = LINE_GROUPS;
+ }
+ }
+
+ // At this point either there is no tail, or there are fewer
+ // than 3 bytes of input available.
+
+ // The main loop, turning 3 input bytes into 4 output bytes on
+ // each iteration.
+ while (p + 3 <= len) {
+ v = ((input[p] & 0xff) << 16) |
+ ((input[p + 1] & 0xff) << 8) |
+ (input[p + 2] & 0xff);
+ output[op] = alphabet[(v >> 18) & 0x3f];
+ output[op + 1] = alphabet[(v >> 12) & 0x3f];
+ output[op + 2] = alphabet[(v >> 6) & 0x3f];
+ output[op + 3] = alphabet[v & 0x3f];
+ p += 3;
+ op += 4;
+ if (--count == 0) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ count = LINE_GROUPS;
+ }
+ }
+
+ if (finish) {
+ // Finish up the tail of the input. Note that we need to
+ // consume any bytes in tail before any bytes
+ // remaining in input; there should be at most two bytes
+ // total.
+
+ if (p - tailLen == len - 1) {
+ int t = 0;
+ v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
+ tailLen -= t;
+ output[op++] = alphabet[(v >> 6) & 0x3f];
+ output[op++] = alphabet[v & 0x3f];
+ if (do_padding) {
+ output[op++] = '=';
+ output[op++] = '=';
+ }
+ if (do_newline) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ }
+ } else if (p - tailLen == len - 2) {
+ int t = 0;
+ v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
+ (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
+ tailLen -= t;
+ output[op++] = alphabet[(v >> 12) & 0x3f];
+ output[op++] = alphabet[(v >> 6) & 0x3f];
+ output[op++] = alphabet[v & 0x3f];
+ if (do_padding) {
+ output[op++] = '=';
+ }
+ if (do_newline) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ }
+ } else if (do_newline && op > 0 && count != LINE_GROUPS) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ }
+
+ if (BuildConfig.DEBUG && (tailLen != 0 || p != len)) {
+ throw new AssertionError();
+ }
+ } else {
+ // Save the leftovers in tail to be consumed on the next
+ // call to encodeInternal.
+
+ if (p == len - 1) {
+ tail[tailLen++] = input[p];
+ } else if (p == len - 2) {
+ tail[tailLen++] = input[p];
+ tail[tailLen++] = input[p + 1];
+ }
+ }
+
+ this.op = op;
+ this.count = count;
+
+ return true;
+ }
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64DataException.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64DataException.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ce9a012ecfda3e8b6bbf5d049da03a37869e7aa
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64DataException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.httplibrary.utils;
+
+import java.io.IOException;
+
+public class Base64DataException extends IOException {
+ public Base64DataException(String detailMessage) {
+ super(detailMessage);
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64OutputStream.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64OutputStream.java
new file mode 100644
index 0000000000000000000000000000000000000000..96a3b8da187eeea6f14746e42ebc55914fc33ca9
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Base64OutputStream.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.httplibrary.utils;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class Base64OutputStream extends FilterOutputStream {
+ private static final byte[] EMPTY = new byte[0];
+ private final Base64.Coder coder;
+ private final int flags;
+ private byte[] buffer = null;
+ private int bpos = 0;
+
+ /**
+ * Performs Base64 encoding on the data written to the stream, writing the encoded data to
+ * another OutputStream.
+ *
+ * @param out the OutputStream to write the encoded data to
+ * @param flags bit flags for controlling the encoder; see the constants in {@link Base64}
+ */
+ public Base64OutputStream(OutputStream out, int flags) {
+ this(out, flags, true);
+ }
+
+ /**
+ * Performs Base64 encoding or decoding on the data written to the stream, writing the
+ * encoded/decoded data to another OutputStream.
+ *
+ * @param out the OutputStream to write the encoded data to
+ * @param flags bit flags for controlling the encoder; see the constants in {@link Base64}
+ * @param encode true to encode, false to decode
+ */
+ public Base64OutputStream(OutputStream out, int flags, boolean encode) {
+ super(out);
+ this.flags = flags;
+ if (encode) {
+ coder = new Base64.Encoder(flags, null);
+ } else {
+ coder = new Base64.Decoder(flags, null);
+ }
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ // To avoid invoking the encoder/decoder routines for single
+ // bytes, we buffer up calls to write(int) in an internal
+ // byte array to transform them into writes of decently-sized
+ // arrays.
+
+ if (buffer == null) {
+ buffer = new byte[1024];
+ }
+ if (bpos >= buffer.length) {
+ // internal buffer full; write it out.
+ internalWrite(buffer, 0, bpos, false);
+ bpos = 0;
+ }
+ buffer[bpos++] = (byte) b;
+ }
+
+ /**
+ * Flush any buffered data from calls to write(int). Needed before doing a write(byte[], int,
+ * int) or a close().
+ */
+ private void flushBuffer() throws IOException {
+ if (bpos > 0) {
+ internalWrite(buffer, 0, bpos, false);
+ bpos = 0;
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (len <= 0) return;
+ flushBuffer();
+ internalWrite(b, off, len, false);
+ }
+
+ @Override
+ public void close() throws IOException {
+ IOException thrown = null;
+ try {
+ flushBuffer();
+ internalWrite(EMPTY, 0, 0, true);
+ } catch (IOException e) {
+ thrown = e;
+ }
+
+ try {
+ if ((flags & Base64.NO_CLOSE) == 0) {
+ out.close();
+ } else {
+ out.flush();
+ }
+ } catch (IOException e) {
+ if (thrown != null) {
+ thrown = e;
+ }
+ }
+
+ if (thrown != null) {
+ throw thrown;
+ }
+ }
+
+ /**
+ * Write the given bytes to the encoder/decoder.
+ *
+ * @param finish true if this is the last batch of input, to cause encoder/decoder state to be
+ * finalized.
+ */
+ private void internalWrite(byte[] b, int off, int len, boolean finish) throws IOException {
+ coder.output = embiggen(coder.output, coder.maxOutputSize(len));
+ if (!coder.process(b, off, len, finish)) {
+ throw new Base64DataException("bad base-64");
+ }
+ out.write(coder.output, 0, coder.op);
+ }
+
+ /**
+ * If b.length is at least len, return b. Otherwise return a new byte array of length len.
+ */
+ private byte[] embiggen(byte[] b, int len) {
+ if (b == null || b.length < len) {
+ return new byte[len];
+ } else {
+ return b;
+ }
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BaseJsonHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BaseJsonHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..f96eb04d8454d573b32d2e68438519bff0f3287e
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BaseJsonHttpResponseHandler.java
@@ -0,0 +1,155 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpStatus;
+
+/**
+ * Class meant to be used with custom JSON parser (such as GSON or Jackson JSON)
+ * {@link #parseResponse(String, boolean)} should be overriden and must return type of generic param
+ * class, response will be then handled to implementation of abstract methods {@link #onSuccess(int,
+ * Header[], String, Object)} or {@link #onFailure(int, Header[],
+ * Throwable, String, Object)}, depending of response HTTP status line (result http code)
+ *
+ * @param Generic type meant to be returned in callback
+ */
+public abstract class BaseJsonHttpResponseHandler extends TextHttpResponseHandler {
+ private static final String LOG_TAG = "BaseJsonHttpRH";
+
+ /**
+ * Creates a new JsonHttpResponseHandler with default charset "UTF-8"
+ */
+ public BaseJsonHttpResponseHandler() {
+ this(DEFAULT_CHARSET);
+ }
+
+ /**
+ * Creates a new JsonHttpResponseHandler with given string encoding
+ *
+ * @param encoding result string encoding, see Charset
+ */
+ public BaseJsonHttpResponseHandler(String encoding) {
+ super(encoding);
+ }
+
+ /**
+ * Base abstract method, handling defined generic type
+ *
+ * @param statusCode HTTP status line
+ * @param headers response headers
+ * @param rawJsonResponse string of response, can be null
+ * @param response response returned by {@link #parseResponse(String, boolean)}
+ */
+ public abstract void onSuccess(int statusCode, Header[] headers, String rawJsonResponse, JSON_TYPE response);
+
+ /**
+ * Base abstract method, handling defined generic type
+ *
+ * @param statusCode HTTP status line
+ * @param headers response headers
+ * @param throwable error thrown while processing request
+ * @param rawJsonData raw string data returned if any
+ * @param errorResponse response returned by {@link #parseResponse(String, boolean)}
+ */
+ public abstract void onFailure(int statusCode, Header[] headers, Throwable throwable, String rawJsonData, JSON_TYPE errorResponse);
+
+ @Override
+ public final void onSuccess(final int statusCode, final Header[] headers, final String responseString) {
+ if (statusCode != HttpStatus.SC_NO_CONTENT) {
+ Runnable parser = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final JSON_TYPE jsonResponse = parseResponse(responseString, false);
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ onSuccess(statusCode, headers, responseString, jsonResponse);
+ }
+ });
+ } catch (final Throwable t) {
+ AsyncHttpClient.log.d(LOG_TAG, "parseResponse thrown an problem", t);
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ onFailure(statusCode, headers, t, responseString, null);
+ }
+ });
+ }
+ }
+ };
+ if (!getUseSynchronousMode() && !getUsePoolThread()) {
+ new Thread(parser).start();
+ } else {
+ // In synchronous mode everything should be run on one thread
+ parser.run();
+ }
+ } else {
+ onSuccess(statusCode, headers, null, null);
+ }
+ }
+
+ @Override
+ public final void onFailure(final int statusCode, final Header[] headers, final String responseString, final Throwable throwable) {
+ if (responseString != null) {
+ Runnable parser = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final JSON_TYPE jsonResponse = parseResponse(responseString, true);
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ onFailure(statusCode, headers, throwable, responseString, jsonResponse);
+ }
+ });
+ } catch (Throwable t) {
+ AsyncHttpClient.log.d(LOG_TAG, "parseResponse thrown an problem", t);
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ onFailure(statusCode, headers, throwable, responseString, null);
+ }
+ });
+ }
+ }
+ };
+ if (!getUseSynchronousMode() && !getUsePoolThread()) {
+ new Thread(parser).start();
+ } else {
+ // In synchronous mode everything should be run on one thread
+ parser.run();
+ }
+ } else {
+ onFailure(statusCode, headers, throwable, null, null);
+ }
+ }
+
+ /**
+ * Should return deserialized instance of generic type, may return object for more vague
+ * handling
+ *
+ * @param rawJsonData response string, may be null
+ * @param isFailure indicating if this method is called from onFailure or not
+ * @return object of generic type or possibly null if you choose so
+ * @throws Throwable allows you to throw anything from within deserializing JSON response
+ */
+ protected abstract JSON_TYPE parseResponse(String rawJsonData, boolean isFailure) throws Throwable;
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BearerAuthSchemeFactory.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BearerAuthSchemeFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..7bfd898c47b1b6c3e01e832cde68593cd7db5403
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BearerAuthSchemeFactory.java
@@ -0,0 +1,83 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpRequest;
+import cz.msebera.android.httpclient.auth.*;
+import cz.msebera.android.httpclient.message.BufferedHeader;
+import cz.msebera.android.httpclient.params.HttpParams;
+import cz.msebera.android.httpclient.protocol.HttpContext;
+import cz.msebera.android.httpclient.util.CharArrayBuffer;
+
+public class BearerAuthSchemeFactory implements AuthSchemeFactory {
+
+ @Override
+ public AuthScheme newInstance(HttpParams params) {
+ return new BearerAuthScheme();
+ }
+
+ public static class BearerAuthScheme implements ContextAwareAuthScheme {
+ private boolean complete = false;
+
+ @Override
+ public void processChallenge(Header header) throws MalformedChallengeException {
+ this.complete = true;
+ }
+
+ @Override
+ public Header authenticate(Credentials credentials, HttpRequest request) throws AuthenticationException {
+ return authenticate(credentials, request, null);
+ }
+
+ @Override
+ public Header authenticate(Credentials credentials, HttpRequest request, HttpContext httpContext)
+ throws AuthenticationException {
+ CharArrayBuffer buffer = new CharArrayBuffer(32);
+ buffer.append(AUTH.WWW_AUTH_RESP);
+ buffer.append(": Bearer ");
+ buffer.append(credentials.getUserPrincipal().getName());
+ return new BufferedHeader(buffer);
+ }
+
+ @Override
+ public String getSchemeName() {
+ return "Bearer";
+ }
+
+ @Override
+ public String getParameter(String name) {
+ return null;
+ }
+
+ @Override
+ public String getRealm() {
+ return null;
+ }
+
+ @Override
+ public boolean isConnectionBased() {
+ return false;
+ }
+
+ @Override
+ public boolean isComplete() {
+ return this.complete;
+ }
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BinaryHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BinaryHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1f76837ffade4af576e8a65099c3c463407aaa1
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BinaryHttpResponseHandler.java
@@ -0,0 +1,160 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpResponse;
+import cz.msebera.android.httpclient.StatusLine;
+import cz.msebera.android.httpclient.client.HttpResponseException;
+import ohos.eventhandler.EventRunner;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Used to intercept and handle the responses from requests made using {@link AsyncHttpClient}.
+ * Receives response body as byte array with a content-type whitelist. (e.g. checks Content-Type
+ * against allowed list, Content-length).
For example:
+ *
+ * AsyncHttpClient client = new AsyncHttpClient();
+ * String[] allowedTypes = new String[] { "image/png" };
+ * client.get("https://www.example.com/image.png", new BinaryHttpResponseHandler(allowedTypes) {
+ * @Override
+ * public void onSuccess(byte[] imageData) {
+ * // Successfully got a response
+ * }
+ *
+ * @Override
+ * public void onFailure(Throwable e, byte[] imageData) {
+ * // Response failed :(
+ * }
+ * });
+ *
+ */
+public abstract class BinaryHttpResponseHandler extends AsyncHttpResponseHandler {
+
+ private static final String LOG_TAG = "BinaryHttpRH";
+
+ private String[] mAllowedContentTypes = new String[]{
+ RequestParams.APPLICATION_OCTET_STREAM,
+ "image/jpeg",
+ "image/png",
+ "image/gif"
+ };
+
+ /**
+ * Creates a new BinaryHttpResponseHandler
+ */
+ public BinaryHttpResponseHandler() {
+ super();
+ }
+
+ /**
+ * Creates a new BinaryHttpResponseHandler, and overrides the default allowed content types with
+ * passed String array (hopefully) of content types.
+ *
+ * @param allowedContentTypes content types array, eg. 'image/jpeg' or pattern '.*'
+ */
+ public BinaryHttpResponseHandler(String[] allowedContentTypes) {
+ super();
+ if (allowedContentTypes != null) {
+ mAllowedContentTypes = allowedContentTypes;
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "Constructor passed allowedContentTypes was null !");
+ }
+ }
+
+ /**
+ * Creates a new BinaryHttpResponseHandler with a user-supplied looper, and overrides the default allowed content types with
+ * passed String array (hopefully) of content types.
+ *
+ * @param allowedContentTypes content types array, eg. 'image/jpeg' or pattern '.*'
+ * @param looper The looper to work with
+ */
+ public BinaryHttpResponseHandler(String[] allowedContentTypes, EventRunner looper) {
+ super(looper);
+ if (allowedContentTypes != null) {
+ mAllowedContentTypes = allowedContentTypes;
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "Constructor passed allowedContentTypes was null !");
+ }
+ }
+
+ /**
+ * Method can be overriden to return allowed content types, can be sometimes better than passing
+ * data in constructor
+ *
+ * @return array of content-types or Pattern string templates (eg. '.*' to match every response)
+ */
+ public String[] getAllowedContentTypes() {
+ return mAllowedContentTypes;
+ }
+
+ @Override
+ public abstract void onSuccess(int statusCode, Header[] headers, byte[] binaryData);
+
+ @Override
+ public abstract void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error);
+
+ @Override
+ public final void sendResponseMessage(HttpResponse response) throws IOException {
+ StatusLine status = response.getStatusLine();
+ Header[] contentTypeHeaders = response.getHeaders(AsyncHttpClient.HEADER_CONTENT_TYPE);
+ if (contentTypeHeaders.length != 1) {
+ //malformed/ambiguous HTTP Header, ABORT!
+ sendFailureMessage(
+ status.getStatusCode(),
+ response.getAllHeaders(),
+ null,
+ new HttpResponseException(
+ status.getStatusCode(),
+ "None, or more than one, Content-Type Header found!"
+ )
+ );
+ return;
+ }
+ Header contentTypeHeader = contentTypeHeaders[0];
+ boolean foundAllowedContentType = false;
+ for (String anAllowedContentType : getAllowedContentTypes()) {
+ try {
+ if (Pattern.matches(anAllowedContentType, contentTypeHeader.getValue())) {
+ foundAllowedContentType = true;
+ }
+ } catch (PatternSyntaxException e) {
+ AsyncHttpClient.log.e(LOG_TAG, "Given pattern is not valid: " + anAllowedContentType, e);
+ }
+ }
+ if (!foundAllowedContentType) {
+ //Content-Type not in allowed list, ABORT!
+ sendFailureMessage(
+ status.getStatusCode(),
+ response.getAllHeaders(),
+ null,
+ new HttpResponseException(
+ status.getStatusCode(),
+ "Content-Type (" + contentTypeHeader.getValue() + ") not allowed!"
+ )
+ );
+ return;
+ }
+ super.sendResponseMessage(response);
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BlackholeHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BlackholeHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..1fb925eae35786fd42a57996af66ccaf306f2573
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/BlackholeHttpResponseHandler.java
@@ -0,0 +1,64 @@
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpResponse;
+
+/**
+ * Blank implementation of ResponseHandlerInterface, which ignores all contents returned by
+ * remote HTTP endpoint, and discards all various log messages
+ *
+ * Use this implementation, if you deliberately want to ignore all response, because you cannot
+ * pass null ResponseHandlerInterface into AsyncHttpClient implementation
+ */
+public class BlackholeHttpResponseHandler extends AsyncHttpResponseHandler {
+
+ @Override
+ public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
+
+ }
+
+ @Override
+ public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
+
+ }
+
+ @Override
+ public void onProgress(long bytesWritten, long totalSize) {
+
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+
+ @Override
+ public void onFinish() {
+
+ }
+
+ @Override
+ public void onPostProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {
+
+ }
+
+ @Override
+ public void onPreProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {
+
+ }
+
+ @Override
+ public void onRetry(int retryNo) {
+
+ }
+
+ @Override
+ public void onStart() {
+
+ }
+
+ @Override
+ public void onUserException(Throwable error) {
+
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/ConscryptSSLProvider.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/ConscryptSSLProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..772c5d2d446fbb0c8640e23843049b72eb986aa5
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/ConscryptSSLProvider.java
@@ -0,0 +1,16 @@
+package com.example.httplibrary.utils;
+
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class ConscryptSSLProvider {
+ static final HiLogLabel label=new HiLogLabel(HiLog.ERROR,0x00101,"网络请求");
+ public static void install(){
+ try {
+// Security.insertProviderAt(Conscrypt.newProviderBuilder().build(),1);
+ }catch (NoClassDefFoundError ex){
+ HiLog.error(label, "","java.lang.NoClassDefFoundError: org.conscrypt.Conscrypt, Please add org.conscrypt.Conscrypt to your dependency");
+ }
+
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/DataAsyncHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/DataAsyncHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..cdbe32eba01e525435b172703134fe85bb4e44b7
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/DataAsyncHttpResponseHandler.java
@@ -0,0 +1,153 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+
+import cz.msebera.android.httpclient.HttpEntity;
+import cz.msebera.android.httpclient.util.ByteArrayBuffer;
+import ohos.eventhandler.InnerEvent;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+@SuppressWarnings("ALL")
+public abstract class DataAsyncHttpResponseHandler extends AsyncHttpResponseHandler {
+ protected static final int PROGRESS_DATA_MESSAGE = 7;
+ private static final String LOG_TAG = "DataAsyncHttpRH";
+
+ /**
+ * Creates a new AsyncHttpResponseHandler
+ */
+ public DataAsyncHttpResponseHandler() {
+ super();
+ }
+
+ /**
+ * Copies elements from {@code original} into a new array, from indexes start (inclusive) to end
+ * (exclusive). The original order of elements is preserved. If {@code end} is greater than
+ * {@code original.length}, the result is padded with the value {@code (byte) 0}.
+ *
+ * @param original the original array
+ * @param start the start index, inclusive
+ * @param end the end index, exclusive
+ * @return the new array
+ * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+ * @throws IllegalArgumentException if {@code start > end}
+ * @throws NullPointerException if {@code original == null}
+ * @see java.util.Arrays
+ * @since 1.6
+ */
+ public static byte[] copyOfRange(byte[] original, int start, int end) throws ArrayIndexOutOfBoundsException, IllegalArgumentException, NullPointerException {
+ if (start > end) {
+ throw new IllegalArgumentException();
+ }
+ int originalLength = original.length;
+ if (start < 0 || start > originalLength) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ int resultLength = end - start;
+ int copyLength = Math.min(resultLength, originalLength - start);
+ byte[] result = new byte[resultLength];
+ System.arraycopy(original, start, result, 0, copyLength);
+ return result;
+ }
+
+ /**
+ * Fired when the request progress, override to handle in your own code
+ *
+ * @param responseBody response body received so far
+ */
+ public void onProgressData(byte[] responseBody) {
+ AsyncHttpClient.log.d(LOG_TAG, "onProgressData(byte[]) was not overriden, but callback was received");
+ }
+
+ final public void sendProgressDataMessage(byte[] responseBytes) {
+ sendMessage(obtainMessage(PROGRESS_DATA_MESSAGE, new Object[]{responseBytes}));
+ }
+
+ // Methods which emulate android's Handler and Message methods
+ @Override
+ protected void handleMessage(InnerEvent message) {
+ super.handleMessage(message);
+ Object[] response;
+
+ switch (message.eventId) {
+ case PROGRESS_DATA_MESSAGE:
+ response = (Object[]) message.object;
+ if (response != null && response.length >= 1) {
+ try {
+ onProgressData((byte[]) response[0]);
+ } catch (Throwable t) {
+ AsyncHttpClient.log.e(LOG_TAG, "custom onProgressData contains an error", t);
+ }
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "PROGRESS_DATA_MESSAGE didn't got enough params");
+ }
+ break;
+ }
+ }
+
+ /**
+ * Returns byte array of response HttpEntity contents
+ *
+ * @param entity can be null
+ * @return response entity body or null
+ * @throws IOException if reading entity or creating byte array failed
+ */
+ @Override
+ byte[] getResponseData(HttpEntity entity) throws IOException {
+
+ byte[] responseBody = null;
+ if (entity != null) {
+ InputStream instream = entity.getContent();
+ if (instream != null) {
+ long contentLength = entity.getContentLength();
+ if (contentLength > Integer.MAX_VALUE) {
+ throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
+ }
+ if (contentLength < 0) {
+ contentLength = BUFFER_SIZE;
+ }
+ try {
+ ByteArrayBuffer buffer = new ByteArrayBuffer((int) contentLength);
+ try {
+ byte[] tmp = new byte[BUFFER_SIZE];
+ int l, count = 0;
+ // do not send messages if request has been cancelled
+ while ((l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) {
+ buffer.append(tmp, 0, l);
+ sendProgressDataMessage(copyOfRange(tmp, 0, l));
+ sendProgressMessage(count, contentLength);
+ }
+ } finally {
+ AsyncHttpClient.silentCloseInputStream(instream);
+ }
+ responseBody = buffer.toByteArray();
+ } catch (OutOfMemoryError e) {
+ System.gc();
+ throw new IOException("File too large to fit into available memory");
+ }
+ }
+ }
+ return responseBody;
+ }
+
+
+}
+
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/FileAsyncHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/FileAsyncHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..dac61790ad3482a77ffbc85058e13e0212643974
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/FileAsyncHttpResponseHandler.java
@@ -0,0 +1,242 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpEntity;
+import ohos.app.Context;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+public abstract class FileAsyncHttpResponseHandler extends AsyncHttpResponseHandler {
+
+ private static final String LOG_TAG = "FileAsyncHttpRH";
+ protected final File file;
+ protected final boolean append;
+ protected final boolean renameIfExists;
+ protected File frontendFile;
+
+ /**
+ * Obtains new FileAsyncHttpResponseHandler and stores response in passed file
+ *
+ * @param file File to store response within, must not be null
+ */
+ public FileAsyncHttpResponseHandler(File file) {
+ this(file, false);
+ }
+
+ /**
+ * Obtains new FileAsyncHttpResponseHandler and stores response in passed file
+ *
+ * @param file File to store response within, must not be null
+ * @param append whether data should be appended to existing file
+ */
+ public FileAsyncHttpResponseHandler(File file, boolean append) {
+ this(file, append, false);
+ }
+
+ /**
+ * Obtains new FileAsyncHttpResponseHandler and stores response in passed file
+ *
+ * @param file File to store response within, must not be null
+ * @param append whether data should be appended to existing file
+ * @param renameTargetFileIfExists whether target file should be renamed if it already exists
+ */
+ public FileAsyncHttpResponseHandler(File file, boolean append, boolean renameTargetFileIfExists) {
+ this(file,append,renameTargetFileIfExists,false);
+ }
+
+
+ /**
+ * Obtains new FileAsyncHttpResponseHandler and stores response in passed file
+ *
+ * @param file File to store response within, must not be null
+ * @param append whether data should be appended to existing file
+ * @param renameTargetFileIfExists whether target file should be renamed if it already exists
+ * @param usePoolThread Whether to use the pool's thread to fire callbacks
+ */
+ public FileAsyncHttpResponseHandler(File file, boolean append, boolean renameTargetFileIfExists,boolean usePoolThread) {
+ super(usePoolThread);
+ Utils.asserts(file != null, "File passed into FileAsyncHttpResponseHandler constructor must not be null");
+ if (!file.isDirectory() && !file.getParentFile().isDirectory()) {
+ Utils.asserts(file.getParentFile().mkdirs(), "Cannot create parent directories for requested File location");
+ }
+ if (file.isDirectory()) {
+ if (!file.mkdirs()) {
+ AsyncHttpClient.log.d(LOG_TAG, "Cannot create directories for requested Directory location, might not be a problem");
+ }
+ }
+ this.file = file;
+ this.append = append;
+ this.renameIfExists = renameTargetFileIfExists;
+ }
+
+ /**
+ * Obtains new FileAsyncHttpResponseHandler against context with target being temporary file
+ *
+ * @param context Context, must not be null
+ */
+ public FileAsyncHttpResponseHandler(Context context) {
+ super();
+ this.file = getTemporaryFile(context);
+ this.append = false;
+ this.renameIfExists = false;
+ }
+
+ /**
+ * Attempts to delete file with stored response
+ *
+ * @return false if the file does not exist or is null, true if it was successfully deleted
+ */
+ public boolean deleteTargetFile() {
+ return getTargetFile() != null && getTargetFile().delete();
+ }
+
+ /**
+ * Used when there is no file to be used when calling constructor
+ *
+ * @param context Context, must not be null
+ * @return temporary file or null if creating file failed
+ */
+ protected File getTemporaryFile(Context context) {
+ Utils.asserts(context != null, "Tried creating temporary file without having Context");
+ try {
+ return File.createTempFile("temp_", "_handled", context.getCacheDir());
+ } catch (IOException e) {
+ AsyncHttpClient.log.e(LOG_TAG, "Cannot create temporary file", e);
+ }
+ return null;
+ }
+
+ /**
+ * Retrieves File object in which the response is stored
+ *
+ * @return File file in which the response was to be stored
+ */
+ protected File getOriginalFile() {
+ Utils.asserts(file != null, "Target file is null, fatal!");
+ return file;
+ }
+
+ /**
+ * Retrieves File which represents response final location after possible renaming
+ *
+ * @return File final target file
+ */
+ public File getTargetFile() {
+ if (frontendFile == null) {
+ frontendFile = getOriginalFile().isDirectory() ? getTargetFileByParsingURL() : getOriginalFile();
+ }
+ return frontendFile;
+ }
+
+ /**
+ * Will return File instance for file representing last URL segment in given folder.
+ * If file already exists and renameTargetFileIfExists was set as true, will try to find file
+ * which doesn't exist, naming template for such cases is "filename.ext" => "filename (%d).ext",
+ * or without extension "filename" => "filename (%d)"
+ *
+ * @return File in given directory constructed by last segment of request URL
+ */
+ protected File getTargetFileByParsingURL() {
+ Utils.asserts(getOriginalFile().isDirectory(), "Target file is not a directory, cannot proceed");
+ Utils.asserts(getRequestURI() != null, "RequestURI is null, cannot proceed");
+ String requestURL = getRequestURI().toString();
+ String filename = requestURL.substring(requestURL.lastIndexOf('/') + 1, requestURL.length());
+ File targetFileRtn = new File(getOriginalFile(), filename);
+ if (targetFileRtn.exists() && renameIfExists) {
+ String format;
+ if (!filename.contains(".")) {
+ format = filename + " (%d)";
+ } else {
+ format = filename.substring(0, filename.lastIndexOf('.')) + " (%d)" + filename.substring(filename.lastIndexOf('.'), filename.length());
+ }
+ int index = 0;
+ while (true) {
+ targetFileRtn = new File(getOriginalFile(), String.format(format, index));
+ if (!targetFileRtn.exists())
+ return targetFileRtn;
+ index++;
+ }
+ }
+ return targetFileRtn;
+ }
+
+ @Override
+ public final void onFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ onFailure(statusCode, headers, throwable, getTargetFile());
+ }
+
+ /**
+ * Method to be overriden, receives as much of file as possible Called when the file is
+ * considered failure or if there is error when retrieving file
+ *
+ * @param statusCode http file status line
+ * @param headers file http headers if any
+ * @param throwable returned throwable
+ * @param file file in which the file is stored
+ */
+ public abstract void onFailure(int statusCode, Header[] headers, Throwable throwable, File file);
+
+ @Override
+ public final void onSuccess(int statusCode, Header[] headers, byte[] responseBytes) {
+ onSuccess(statusCode, headers, getTargetFile());
+ }
+
+ /**
+ * Method to be overriden, receives as much of response as possible
+ *
+ * @param statusCode http response status line
+ * @param headers response http headers if any
+ * @param file file in which the response is stored
+ */
+ public abstract void onSuccess(int statusCode, Header[] headers, File file);
+
+ @Override
+ protected byte[] getResponseData(HttpEntity entity) throws IOException {
+ if (entity != null) {
+ InputStream instream = entity.getContent();
+ long contentLength = entity.getContentLength();
+ FileOutputStream buffer = new FileOutputStream(getTargetFile(), this.append);
+ if (instream != null) {
+ try {
+ byte[] tmp = new byte[BUFFER_SIZE];
+ int l, count = 0;
+ // do not send messages if request has been cancelled
+ while ((l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) {
+ count += l;
+ buffer.write(tmp, 0, l);
+ sendProgressMessage(count, contentLength);
+ }
+ } finally {
+ AsyncHttpClient.silentCloseInputStream(instream);
+ buffer.flush();
+ AsyncHttpClient.silentCloseOutputStream(buffer);
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/HttpDelete.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/HttpDelete.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9130006e426622f8131f0cb46f51ad7f70e5f38
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/HttpDelete.java
@@ -0,0 +1,59 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.client.methods.HttpEntityEnclosingRequestBase;
+
+import java.net.URI;
+
+/**
+ * The current Android (API level 21) bundled version of the Apache Http Client does not implement
+ * a HttpEntityEnclosingRequestBase type of HTTP DELETE method.
+ * Until the Android version is updated this can serve in it's stead.
+ * This implementation can and should go away when the official solution arrives.
+ */
+public final class HttpDelete extends HttpEntityEnclosingRequestBase {
+ public final static String METHOD_NAME = "DELETE";
+
+ public HttpDelete() {
+ super();
+ }
+
+ /**
+ * @param uri target url as URI
+ */
+ public HttpDelete(final URI uri) {
+ super();
+ setURI(uri);
+ }
+
+ /**
+ * @param uri target url as String
+ * @throws IllegalArgumentException if the uri is invalid.
+ */
+ public HttpDelete(final String uri) {
+ super();
+ setURI(URI.create(uri));
+ }
+
+ @Override
+ public String getMethod() {
+ return METHOD_NAME;
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/HttpGet.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/HttpGet.java
new file mode 100644
index 0000000000000000000000000000000000000000..cab73ae1d9476caeb4dde46d68b83e1f983633d4
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/HttpGet.java
@@ -0,0 +1,60 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.client.methods.HttpEntityEnclosingRequestBase;
+
+import java.net.URI;
+
+/**
+ * The current Android (API level 21) bundled version of the Apache Http Client does not implement
+ * a HttpEntityEnclosingRequestBase type of HTTP GET method.
+ * Until the Android version is updated this can serve in it's stead.
+ * This implementation can and should go away when the official solution arrives.
+ */
+public final class HttpGet extends HttpEntityEnclosingRequestBase {
+
+ public final static String METHOD_NAME = "GET";
+
+ public HttpGet() {
+ super();
+ }
+
+ /**
+ * @param uri target url as URI
+ */
+ public HttpGet(final URI uri) {
+ super();
+ setURI(uri);
+ }
+
+ /**
+ * @param uri target url as String
+ * @throws IllegalArgumentException if the uri is invalid.
+ */
+ public HttpGet(final String uri) {
+ super();
+ setURI(URI.create(uri));
+ }
+
+ @Override
+ public String getMethod() {
+ return METHOD_NAME;
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..85bd67eeb3f9124d492661a2a01a1e9d36da5f3c
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonHttpResponseHandler.java
@@ -0,0 +1,284 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpStatus;
+
+/**
+ * Used to intercept and handle the responses from requests made using {@link AsyncHttpClient}, with
+ * automatic parsing into a {@link JsonObject} or {@link JsonArray}.
This class is
+ * designed to be passed to get, post, put and delete requests with the or methods anonymously overridden.
+ * Additionally, you can override the other event methods from the parent class.
+ */
+public class JsonHttpResponseHandler extends TextHttpResponseHandler {
+
+ private static final String LOG_TAG = "JsonHttpRH";
+
+
+ private boolean useRFC5179CompatibilityMode = true;
+
+ /**
+ * Creates new JsonHttpResponseHandler, with JSON String encoding UTF-8
+ */
+ public JsonHttpResponseHandler() {
+ super(DEFAULT_CHARSET);
+ }
+
+ /**
+ * Creates new JsonHttpResponseHandler with given JSON String encoding
+ *
+ * @param encoding String encoding to be used when parsing JSON
+ */
+ public JsonHttpResponseHandler(String encoding) {
+ super(encoding);
+ }
+
+ /**
+ * Creates new JsonHttpResponseHandler with JSON String encoding UTF-8 and given RFC5179CompatibilityMode
+ *
+ * @param useRFC5179CompatibilityMode Boolean mode to use RFC5179 or latest
+ */
+ public JsonHttpResponseHandler(boolean useRFC5179CompatibilityMode) {
+ super(DEFAULT_CHARSET);
+ this.useRFC5179CompatibilityMode = useRFC5179CompatibilityMode;
+ }
+
+ /**
+ * Creates new JsonHttpResponseHandler with given JSON String encoding and RFC5179CompatibilityMode
+ *
+ * @param encoding String encoding to be used when parsing JSON
+ * @param useRFC5179CompatibilityMode Boolean mode to use RFC5179 or latest
+ */
+ public JsonHttpResponseHandler(String encoding, boolean useRFC5179CompatibilityMode) {
+ super(encoding);
+ this.useRFC5179CompatibilityMode = useRFC5179CompatibilityMode;
+ }
+
+ /**
+ * Returns when request succeeds
+ *
+ * @param statusCode http response status line
+ * @param headers response headers if any
+ * @param response parsed response if any
+ */
+ public void onSuccess(int statusCode, Header[] headers, JsonObject response) {
+ AsyncHttpClient.log.w(LOG_TAG, "onSuccess(int, Header[], JSONObject) was not overriden, but callback was received");
+ }
+
+ /**
+ * Returns when request succeeds
+ *
+ * @param statusCode http response status line
+ * @param headers response headers if any
+ * @param response parsed response if any
+ */
+ public void onSuccess(int statusCode, Header[] headers, JsonArray response) {
+ AsyncHttpClient.log.w(LOG_TAG, "onSuccess(int, Header[], JSONArray) was not overriden, but callback was received");
+ }
+
+ /**
+ * Returns when request failed
+ *
+ * @param statusCode http response status line
+ * @param headers response headers if any
+ * @param throwable throwable describing the way request failed
+ * @param errorResponse parsed response if any
+ */
+ public void onFailure(int statusCode, Header[] headers, Throwable throwable, JsonObject errorResponse) {
+ AsyncHttpClient.log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONObject) was not overriden, but callback was received", throwable);
+ }
+
+ /**
+ * Returns when request failed
+ *
+ * @param statusCode http response status line
+ * @param headers response headers if any
+ * @param throwable throwable describing the way request failed
+ * @param errorResponse parsed response if any
+ */
+ public void onFailure(int statusCode, Header[] headers, Throwable throwable, JsonArray errorResponse) {
+ AsyncHttpClient.log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONArray) was not overriden, but callback was received", throwable);
+ }
+
+ @Override
+ public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
+ AsyncHttpClient.log.w(LOG_TAG, "onFailure(int, Header[], String, Throwable) was not overriden, but callback was received", throwable);
+ }
+
+ @Override
+ public void onSuccess(int statusCode, Header[] headers, String responseString) {
+ AsyncHttpClient.log.w(LOG_TAG, "onSuccess(int, Header[], String) was not overriden, but callback was received");
+ }
+
+ @Override
+ public final void onSuccess(final int statusCode, final Header[] headers, final byte[] responseBytes) {
+ if (statusCode != HttpStatus.SC_NO_CONTENT) {
+ Runnable parser = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final Object jsonResponse = parseResponse(responseBytes);
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ // In RFC5179 a null value is not a valid JSON
+ if (!useRFC5179CompatibilityMode && jsonResponse == null) {
+ onSuccess(statusCode, headers, (String) null);
+ } else if (jsonResponse instanceof JsonObject) {
+ onSuccess(statusCode, headers, (JsonObject) jsonResponse);
+ } else if (jsonResponse instanceof JsonArray) {
+ onSuccess(statusCode, headers, (JsonArray) jsonResponse);
+ } else if (jsonResponse instanceof String) {
+ // In RFC5179 a simple string value is not a valid JSON
+ if (useRFC5179CompatibilityMode) {
+ AsyncHttpClient.log.e(LOG_TAG, "失败1");
+// onFailure(statusCode, headers, (String) jsonResponse, new JsonParseException("Response cannot be parsed as JSON data"));
+ onSuccess(statusCode, headers, (String) jsonResponse);
+ } else {
+ onSuccess(statusCode, headers, (String) jsonResponse);
+ }
+ } else {
+ AsyncHttpClient.log.e(LOG_TAG, "失败2");
+ onFailure(statusCode, headers, new JsonParseException("Unexpected response type " + jsonResponse.getClass().getName()), (JsonObject) null);
+// onSuccess(statusCode,headers,(String) jsonResponse);
+ }
+ }
+ });
+ } catch (final Exception ex) {
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ onFailure(statusCode, headers, ex, (JsonObject) null);
+ }
+ });
+ }
+ }
+ };
+ if (!getUseSynchronousMode() && !getUsePoolThread()) {
+ new Thread(parser).start();
+ } else {
+ // In synchronous mode everything should be run on one thread
+ parser.run();
+ }
+ } else {
+ onSuccess(statusCode, headers, new JsonObject());
+ }
+ }
+
+ @Override
+ public final void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) {
+ if (responseBytes != null) {
+ Runnable parser = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final Object jsonResponse = parseResponse(responseBytes);
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ // In RFC5179 a null value is not a valid JSON
+ if (!useRFC5179CompatibilityMode && jsonResponse == null) {
+ onFailure(statusCode, headers, (String) null, throwable);
+ } else if (jsonResponse instanceof JsonObject) {
+ onFailure(statusCode, headers, throwable, (JsonObject) jsonResponse);
+ } else if (jsonResponse instanceof JsonArray) {
+ onFailure(statusCode, headers, throwable, (JsonArray) jsonResponse);
+ } else if (jsonResponse instanceof String) {
+ onFailure(statusCode, headers, (String) jsonResponse, throwable);
+ } else {
+ onFailure(statusCode, headers, new JsonParseException("Unexpected response type " + jsonResponse.getClass().getName()), (JsonObject) null);
+ }
+ }
+ });
+
+ } catch (final Exception ex) {
+ postRunnable(new Runnable() {
+ @Override
+ public void run() {
+ onFailure(statusCode, headers, ex, (JsonObject) null);
+ }
+ });
+
+ }
+ }
+ };
+ if (!getUseSynchronousMode() && !getUsePoolThread()) {
+ new Thread(parser).start();
+ } else {
+ // In synchronous mode everything should be run on one thread
+ parser.run();
+ }
+ } else {
+ AsyncHttpClient.log.v(LOG_TAG, "response body is null, calling onFailure(Throwable, JSONObject)");
+ onFailure(statusCode, headers, throwable, (JsonObject) null);
+ }
+ }
+
+
+ protected Object parseResponse(byte[] responseBody) throws JsonParseException {
+ if (null == responseBody)
+ return null;
+ Object result = null;
+ //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If JSON is not valid this will return null
+ String jsonString = getResponseString(responseBody, getCharset());
+ result=jsonString;
+ AsyncHttpClient.log.v(LOG_TAG, "zel-ResponseString:"+jsonString);
+
+// if (jsonString != null) {
+// jsonString = jsonString.trim();
+// if (useRFC5179CompatibilityMode) {
+// if (jsonString.startsWith("{") || jsonString.startsWith("[")) {
+// result = new Gson().toJson(jsonString);
+// }
+// } else {
+// // Check if the string is an JSONObject style {} or JSONArray style []
+// // If not we consider this as a string
+// if ((jsonString.startsWith("{") && jsonString.endsWith("}"))
+// || jsonString.startsWith("[") && jsonString.endsWith("]")) {
+// result = new JSONTokener(jsonString).nextValue();
+// result = new Gson().toJson(jsonString);
+// }
+// // Check if this is a String "my String value" and remove quote
+// // Other value type (numerical, boolean) should be without quote
+// else if (jsonString.startsWith("\"") && jsonString.endsWith("\"")) {
+// result = jsonString.substring(1, jsonString.length() - 1);
+// }
+// }
+// }
+ if (result == null) {
+ result = jsonString;
+ }
+ return result;
+ }
+
+ public boolean isUseRFC5179CompatibilityMode() {
+ return useRFC5179CompatibilityMode;
+ }
+
+ public void setUseRFC5179CompatibilityMode(boolean useRFC5179CompatibilityMode) {
+ this.useRFC5179CompatibilityMode = useRFC5179CompatibilityMode;
+ }
+
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonStreamerEntity.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonStreamerEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..601299c0a80d234f82acc0f170c496d4f395e0ff
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonStreamerEntity.java
@@ -0,0 +1,391 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+
+import com.google.gson.JsonObject;
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpEntity;
+import cz.msebera.android.httpclient.message.BasicHeader;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * HTTP entity to upload JSON data using streams. This has very low memory footprint; suitable for
+ * uploading large files using base64 encoding.
+ */
+public class JsonStreamerEntity implements HttpEntity {
+
+ private static final String LOG_TAG = "JsonStreamerEntity";
+
+ private static final UnsupportedOperationException ERR_UNSUPPORTED =
+ new UnsupportedOperationException("Unsupported operation in this implementation.");
+
+ // Size of the byte-array buffer used in I/O streams.
+ private static final int BUFFER_SIZE = 4096;
+ private static final byte[] JSON_TRUE = "true".getBytes();
+ private static final byte[] JSON_FALSE = "false".getBytes();
+ private static final byte[] JSON_NULL = "null".getBytes();
+ private static final byte[] STREAM_NAME = escape("name");
+ private static final byte[] STREAM_TYPE = escape("type");
+ private static final byte[] STREAM_CONTENTS = escape("contents");
+ private static final Header HEADER_JSON_CONTENT =
+ new BasicHeader(
+ AsyncHttpClient.HEADER_CONTENT_TYPE,
+ RequestParams.APPLICATION_JSON);
+ private static final Header HEADER_GZIP_ENCODING =
+ new BasicHeader(
+ AsyncHttpClient.HEADER_CONTENT_ENCODING,
+ AsyncHttpClient.ENCODING_GZIP);
+ // Buffer used for reading from input streams.
+ private final byte[] buffer = new byte[BUFFER_SIZE];
+ // JSON data and associated meta-data to be uploaded.
+ private final Map jsonParams = new HashMap();
+
+ // Whether to use gzip compression while uploading
+ private final Header contentEncoding;
+
+ private final byte[] elapsedField;
+
+ private final ResponseHandlerInterface progressHandler;
+
+ public JsonStreamerEntity(ResponseHandlerInterface progressHandler, boolean useGZipCompression, String elapsedField) {
+ this.progressHandler = progressHandler;
+ this.contentEncoding = useGZipCompression ? HEADER_GZIP_ENCODING : null;
+ this.elapsedField = elapsedField.isEmpty()
+ ? null
+ : escape(elapsedField);
+ }
+
+ // Curtosy of Simple-JSON: https://goo.gl/XoW8RF
+ // Changed a bit to suit our needs in this class.
+ static byte[] escape(String string) {
+ // If it's null, just return prematurely.
+ if (string == null) {
+ return JSON_NULL;
+ }
+
+ // Create a string builder to generate the escaped string.
+ StringBuilder sb = new StringBuilder(128);
+
+ // Surround with quotations.
+ sb.append('"');
+
+ int length = string.length(), pos = -1;
+ while (++pos < length) {
+ char ch = string.charAt(pos);
+ switch (ch) {
+ case '"':
+ sb.append("\\\"");
+ break;
+ case '\\':
+ sb.append("\\\\");
+ break;
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ default:
+ // Reference: https://www.unicode.org/versions/Unicode5.1.0/
+ if ((ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) {
+ String intString = Integer.toHexString(ch);
+ sb.append("\\u");
+ int intLength = 4 - intString.length();
+ for (int zero = 0; zero < intLength; zero++) {
+ sb.append('0');
+ }
+ sb.append(intString.toUpperCase(Locale.US));
+ } else {
+ sb.append(ch);
+ }
+ break;
+ }
+ }
+
+ // Surround with quotations.
+ sb.append('"');
+
+ return sb.toString().getBytes();
+ }
+
+ /**
+ * Add content parameter, identified by the given key, to the request.
+ *
+ * @param key entity's name
+ * @param value entity's value (Scalar, FileWrapper, StreamWrapper)
+ */
+ public void addPart(String key, Object value) {
+ jsonParams.put(key, value);
+ }
+
+ @Override
+ public boolean isRepeatable() {
+ return false;
+ }
+
+ @Override
+ public boolean isChunked() {
+ return false;
+ }
+
+ @Override
+ public boolean isStreaming() {
+ return false;
+ }
+
+ @Override
+ public long getContentLength() {
+ return -1;
+ }
+
+ @Override
+ public Header getContentEncoding() {
+ return contentEncoding;
+ }
+
+ @Override
+ public Header getContentType() {
+ return HEADER_JSON_CONTENT;
+ }
+
+ @Override
+ public void consumeContent() throws IOException, UnsupportedOperationException {
+ }
+
+ @Override
+ public InputStream getContent() throws IOException, UnsupportedOperationException {
+ throw ERR_UNSUPPORTED;
+ }
+
+ @Override
+ public void writeTo(final OutputStream out) throws IOException {
+ if (out == null) {
+ throw new IllegalStateException("Output stream cannot be null.");
+ }
+
+ // Record the time when uploading started.
+ long now = System.currentTimeMillis();
+
+ // Use GZIP compression when sending streams, otherwise just use
+ // a buffered output stream to speed things up a bit.
+ OutputStream os = contentEncoding != null
+ ? new GZIPOutputStream(out, BUFFER_SIZE)
+ : out;
+
+ // Always send a JSON object.
+ os.write('{');
+
+ // Keys used by the HashMaps.
+ Set keys = jsonParams.keySet();
+
+ int keysCount = keys.size();
+ if (0 < keysCount) {
+ int keysProcessed = 0;
+ boolean isFileWrapper;
+
+ // Go over all keys and handle each's value.
+ for (String key : keys) {
+ // Indicate that this key has been processed.
+ keysProcessed++;
+
+ try {
+ // Evaluate the value (which cannot be null).
+ Object value = jsonParams.get(key);
+
+ // Write the JSON object's key.
+ os.write(escape(key));
+ os.write(':');
+
+ // Bail out prematurely if value's null.
+ if (value == null) {
+ os.write(JSON_NULL);
+ } else {
+ // Check if this is a FileWrapper.
+ isFileWrapper = value instanceof RequestParams.FileWrapper;
+
+ // If a file should be uploaded.
+ if (isFileWrapper || value instanceof RequestParams.StreamWrapper) {
+ // All uploads are sent as an object containing the file's details.
+ os.write('{');
+
+ // Determine how to handle this entry.
+ if (isFileWrapper) {
+ writeToFromFile(os, (RequestParams.FileWrapper) value);
+ } else {
+ writeToFromStream(os, (RequestParams.StreamWrapper) value);
+ }
+
+ // End the file's object and prepare for next one.
+ os.write('}');
+ } else if (value instanceof JsonValueInterface) {
+ os.write(((JsonValueInterface) value).getEscapedJsonValue());
+ } else if (value instanceof JsonObject) {
+ os.write(value.toString().getBytes());
+ } else if (value instanceof JsonObject) {
+ os.write(value.toString().getBytes());
+ } else if (value instanceof Boolean) {
+ os.write((Boolean) value ? JSON_TRUE : JSON_FALSE);
+ } else if (value instanceof Long) {
+ os.write((((Number) value).longValue() + "").getBytes());
+ } else if (value instanceof Double) {
+ os.write((((Number) value).doubleValue() + "").getBytes());
+ } else if (value instanceof Float) {
+ os.write((((Number) value).floatValue() + "").getBytes());
+ } else if (value instanceof Integer) {
+ os.write((((Number) value).intValue() + "").getBytes());
+ } else {
+ os.write(escape(value.toString()));
+ }
+ }
+ } finally {
+ // Separate each K:V with a comma, except the last one.
+ if (elapsedField != null || keysProcessed < keysCount) {
+ os.write(',');
+ }
+ }
+ }
+
+ // Calculate how many milliseconds it took to upload the contents.
+ long elapsedTime = System.currentTimeMillis() - now;
+
+ // Include the elapsed time taken to upload everything.
+ // This might be useful for somebody, but it serves us well since
+ // there will almost always be a ',' as the last sent character.
+ if (elapsedField != null) {
+ os.write(elapsedField);
+ os.write(':');
+ os.write((elapsedTime + "").getBytes());
+ }
+
+ AsyncHttpClient.log.i(LOG_TAG, "Uploaded JSON in " + Math.floor(elapsedTime / 1000) + " seconds");
+ }
+
+ // Close the JSON object.
+ os.write('}');
+
+ // Flush the contents up the stream.
+ os.flush();
+ AsyncHttpClient.silentCloseOutputStream(os);
+ }
+
+ private void writeToFromStream(OutputStream os, RequestParams.StreamWrapper entry)
+ throws IOException {
+
+ // Send the meta data.
+ writeMetaData(os, entry.name, entry.contentType);
+
+ int bytesRead;
+
+ // Upload the file's contents in Base64.
+ Base64OutputStream bos =
+ new Base64OutputStream(os, Base64.NO_CLOSE | Base64.NO_WRAP);
+
+ // Read from input stream until no more data's left to read.
+ while ((bytesRead = entry.inputStream.read(buffer)) != -1) {
+ bos.write(buffer, 0, bytesRead);
+ }
+
+ // Close the Base64 output stream.
+ AsyncHttpClient.silentCloseOutputStream(bos);
+
+ // End the meta data.
+ endMetaData(os);
+
+ // Close input stream.
+ if (entry.autoClose) {
+ // Safely close the input stream.
+ AsyncHttpClient.silentCloseInputStream(entry.inputStream);
+ }
+ }
+
+ private void writeToFromFile(OutputStream os, RequestParams.FileWrapper wrapper)
+ throws IOException {
+
+ // Send the meta data.
+ writeMetaData(os, wrapper.file.getName(), wrapper.contentType);
+
+ int bytesRead;
+ long bytesWritten = 0, totalSize = wrapper.file.length();
+
+ // Open the file for reading.
+ FileInputStream in = new FileInputStream(wrapper.file);
+
+ // Upload the file's contents in Base64.
+ Base64OutputStream bos =
+ new Base64OutputStream(os, Base64.NO_CLOSE | Base64.NO_WRAP);
+
+ // Read from file until no more data's left to read.
+ while ((bytesRead = in.read(buffer)) != -1) {
+ bos.write(buffer, 0, bytesRead);
+ bytesWritten += bytesRead;
+ progressHandler.sendProgressMessage(bytesWritten, totalSize);
+ }
+
+ // Close the Base64 output stream.
+ AsyncHttpClient.silentCloseOutputStream(bos);
+
+ // End the meta data.
+ endMetaData(os);
+
+ // Safely close the input stream.
+ AsyncHttpClient.silentCloseInputStream(in);
+ }
+
+ private void writeMetaData(OutputStream os, String name, String contentType) throws IOException {
+ // Send the streams's name.
+ os.write(STREAM_NAME);
+ os.write(':');
+ os.write(escape(name));
+ os.write(',');
+
+ // Send the streams's content type.
+ os.write(STREAM_TYPE);
+ os.write(':');
+ os.write(escape(contentType));
+ os.write(',');
+
+ // Prepare the file content's key.
+ os.write(STREAM_CONTENTS);
+ os.write(':');
+ os.write('"');
+ }
+
+ private void endMetaData(OutputStream os) throws IOException {
+ os.write('"');
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonValueInterface.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonValueInterface.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bb03fbfc3d12820973642f4526d935362ed7679
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/JsonValueInterface.java
@@ -0,0 +1,30 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+
+public interface JsonValueInterface {
+
+ /**
+ * Returns the escaped, ready-to-be used value of this encapsulated object.
+ *
+ * @return byte array holding the data to be used (as-is) in a JSON object
+ */
+ byte[] getEscapedJsonValue();
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/LogHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/LogHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..470d17d8d17da24793a533e9905cc0be62d683f9
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/LogHandler.java
@@ -0,0 +1,129 @@
+package com.example.httplibrary.utils;
+
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class LogHandler implements LogInterface {
+ static final HiLogLabel label=new HiLogLabel(HiLog.DEBUG,0x00101,"网络请求");
+
+ boolean mLoggingEnabled = true;
+ int mLoggingLevel = VERBOSE;
+
+ @Override
+ public boolean isLoggingEnabled() {
+ return mLoggingEnabled;
+ }
+
+ @Override
+ public void setLoggingEnabled(boolean loggingEnabled) {
+ this.mLoggingEnabled = loggingEnabled;
+ }
+
+ @Override
+ public int getLoggingLevel() {
+ return mLoggingLevel;
+ }
+
+ @Override
+ public void setLoggingLevel(int loggingLevel) {
+ this.mLoggingLevel = loggingLevel;
+ }
+
+ @Override
+ public boolean shouldLog(int logLevel) {
+ return logLevel >= mLoggingLevel;
+ }
+
+ public void log(int logLevel, String tag, String msg) {
+ logWithThrowable(logLevel, tag, msg, null);
+ }
+
+ public void logWithThrowable(int logLevel, String tag, String msg, Throwable t) {
+ if (isLoggingEnabled() && shouldLog(logLevel)) {
+ switch (logLevel) {
+ case VERBOSE:
+ HiLog.fatal(label, msg, t);
+ break;
+ case WARN:
+ HiLog.warn(label, msg, t);
+ break;
+ case ERROR:
+ HiLog.error(label, msg, t);
+ break;
+ case DEBUG:
+ HiLog.debug(label, msg, t);
+ break;
+ case WTF:
+ checkedWtf(tag, msg, t);
+ break;
+ case INFO:
+ HiLog.info(label, msg, t);
+ break;
+ }
+ }
+ }
+
+ private void checkedWtf(String tag, String msg, Throwable t) {
+ HiLog.error(label, msg, t);
+ }
+
+ @Override
+ public void v(String tag, String msg) {
+ log(VERBOSE, tag, msg);
+ }
+
+ @Override
+ public void v(String tag, String msg, Throwable t) {
+ logWithThrowable(VERBOSE, tag, msg, t);
+ }
+
+ @Override
+ public void d(String tag, String msg) {
+ log(VERBOSE, tag, msg);
+ }
+
+ @Override
+ public void d(String tag, String msg, Throwable t) {
+ logWithThrowable(DEBUG, tag, msg, t);
+ }
+
+ @Override
+ public void i(String tag, String msg) {
+ log(INFO, tag, msg);
+ }
+
+ @Override
+ public void i(String tag, String msg, Throwable t) {
+ logWithThrowable(INFO, tag, msg, t);
+ }
+
+ @Override
+ public void w(String tag, String msg) {
+ log(WARN, tag, msg);
+ }
+
+ @Override
+ public void w(String tag, String msg, Throwable t) {
+ logWithThrowable(WARN, tag, msg, t);
+ }
+
+ @Override
+ public void e(String tag, String msg) {
+ log(ERROR, tag, msg);
+ }
+
+ @Override
+ public void e(String tag, String msg, Throwable t) {
+ logWithThrowable(ERROR, tag, msg, t);
+ }
+
+ @Override
+ public void wtf(String tag, String msg) {
+ log(WTF, tag, msg);
+ }
+
+ @Override
+ public void wtf(String tag, String msg, Throwable t) {
+ logWithThrowable(WTF, tag, msg, t);
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/LogInterface.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/LogInterface.java
new file mode 100644
index 0000000000000000000000000000000000000000..280cf94c68d12302f43a100653ba043aba8e7175
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/LogInterface.java
@@ -0,0 +1,47 @@
+package com.example.httplibrary.utils;
+
+public interface LogInterface {
+
+ int VERBOSE = 2;
+ int DEBUG = 3;
+ int INFO = 4;
+ int WARN = 5;
+ int ERROR = 6;
+ int WTF = 8;
+
+ boolean isLoggingEnabled();
+
+ void setLoggingEnabled(boolean loggingEnabled);
+
+ int getLoggingLevel();
+
+ void setLoggingLevel(int loggingLevel);
+
+ boolean shouldLog(int logLevel);
+
+ void v(String tag, String msg);
+
+ void v(String tag, String msg, Throwable t);
+
+ void d(String tag, String msg);
+
+ void d(String tag, String msg, Throwable t);
+
+ void i(String tag, String msg);
+
+ void i(String tag, String msg, Throwable t);
+
+ void w(String tag, String msg);
+
+ void w(String tag, String msg, Throwable t);
+
+ void e(String tag, String msg);
+
+ void e(String tag, String msg, Throwable t);
+
+ void wtf(String tag, String msg);
+
+ void wtf(String tag, String msg, Throwable t);
+
+
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/MyRedirectHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/MyRedirectHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..f86db445999e3be52bb1d1f37afe2040a5768f79
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/MyRedirectHandler.java
@@ -0,0 +1,161 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2014 Aymon Fournier
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.*;
+import cz.msebera.android.httpclient.client.CircularRedirectException;
+import cz.msebera.android.httpclient.client.params.ClientPNames;
+import cz.msebera.android.httpclient.client.utils.URIUtils;
+import cz.msebera.android.httpclient.impl.client.DefaultRedirectHandler;
+import cz.msebera.android.httpclient.impl.client.RedirectLocations;
+import cz.msebera.android.httpclient.params.HttpParams;
+import cz.msebera.android.httpclient.protocol.ExecutionContext;
+import cz.msebera.android.httpclient.protocol.HttpContext;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * Taken from StackOverflow
+ *
+ * @author Aymon Fournier, aymon.fournier@gmail.com
+ * @see https://stackoverflow.com/questions/3420767/httpclient-redirecting-to-url-with-spaces-throwing-exception
+ */
+class MyRedirectHandler extends DefaultRedirectHandler {
+
+ private static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations";
+ private final boolean enableRedirects;
+
+ public MyRedirectHandler(final boolean allowRedirects) {
+ super();
+ this.enableRedirects = allowRedirects;
+ }
+
+ @Override
+ public boolean isRedirectRequested(
+ final HttpResponse response,
+ final HttpContext context) {
+ if (!enableRedirects) {
+ return false;
+ }
+ if (response == null) {
+ throw new IllegalArgumentException("HTTP response may not be null");
+ }
+ int statusCode = response.getStatusLine().getStatusCode();
+ switch (statusCode) {
+ case HttpStatus.SC_MOVED_TEMPORARILY:
+ case HttpStatus.SC_MOVED_PERMANENTLY:
+ case HttpStatus.SC_SEE_OTHER:
+ case HttpStatus.SC_TEMPORARY_REDIRECT:
+ return true;
+ default:
+ return false;
+ } //end of switch
+ }
+
+ @Override
+ public URI getLocationURI(
+ final HttpResponse response,
+ final HttpContext context) throws ProtocolException {
+ if (response == null) {
+ throw new IllegalArgumentException("HTTP response may not be null");
+ }
+ //get the location header to find out where to redirect to
+ Header locationHeader = response.getFirstHeader("location");
+ if (locationHeader == null) {
+ // got a redirect response, but no location header
+ throw new ProtocolException(
+ "Received redirect response " + response.getStatusLine()
+ + " but no location header"
+ );
+ }
+ //HERE IS THE MODIFIED LINE OF CODE
+ String location = locationHeader.getValue().replaceAll(" ", "%20");
+
+ URI uri;
+ try {
+ uri = new URI(location);
+ } catch (URISyntaxException ex) {
+ throw new ProtocolException("Invalid redirect URI: " + location, ex);
+ }
+
+ HttpParams params = response.getParams();
+ // rfc2616 demands the location value be a complete URI
+ // Location = "Location" ":" absoluteURI
+ if (!uri.isAbsolute()) {
+ if (params.isParameterTrue(ClientPNames.REJECT_RELATIVE_REDIRECT)) {
+ throw new ProtocolException("Relative redirect location '"
+ + uri + "' not allowed");
+ }
+ // Adjust location URI
+ HttpHost target = (HttpHost) context.getAttribute(
+ ExecutionContext.HTTP_TARGET_HOST);
+ if (target == null) {
+ throw new IllegalStateException("Target host not available " +
+ "in the HTTP context");
+ }
+
+ HttpRequest request = (HttpRequest) context.getAttribute(
+ ExecutionContext.HTTP_REQUEST);
+
+ try {
+ URI requestURI = new URI(request.getRequestLine().getUri());
+ URI absoluteRequestURI = URIUtils.rewriteURI(requestURI, target, true);
+ uri = URIUtils.resolve(absoluteRequestURI, uri);
+ } catch (URISyntaxException ex) {
+ throw new ProtocolException(ex.getMessage(), ex);
+ }
+ }
+
+ if (params.isParameterFalse(ClientPNames.ALLOW_CIRCULAR_REDIRECTS)) {
+
+ RedirectLocations redirectLocations = (RedirectLocations) context.getAttribute(
+ REDIRECT_LOCATIONS);
+
+ if (redirectLocations == null) {
+ redirectLocations = new RedirectLocations();
+ context.setAttribute(REDIRECT_LOCATIONS, redirectLocations);
+ }
+
+ URI redirectURI;
+ if (uri.getFragment() != null) {
+ try {
+ HttpHost target = new HttpHost(
+ uri.getHost(),
+ uri.getPort(),
+ uri.getScheme());
+ redirectURI = URIUtils.rewriteURI(uri, target, true);
+ } catch (URISyntaxException ex) {
+ throw new ProtocolException(ex.getMessage(), ex);
+ }
+ } else {
+ redirectURI = uri;
+ }
+
+ if (redirectLocations.contains(redirectURI)) {
+ throw new CircularRedirectException("Circular redirect to '" +
+ redirectURI + "'");
+ } else {
+ redirectLocations.add(redirectURI);
+ }
+ }
+
+ return uri;
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/MySSLSocketFactory.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/MySSLSocketFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..d30ba4b4ff78fe3b25cf5130eed6112ae812ed78
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/MySSLSocketFactory.java
@@ -0,0 +1,220 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.HttpVersion;
+import cz.msebera.android.httpclient.conn.ClientConnectionManager;
+import cz.msebera.android.httpclient.conn.scheme.PlainSocketFactory;
+import cz.msebera.android.httpclient.conn.scheme.Scheme;
+import cz.msebera.android.httpclient.conn.scheme.SchemeRegistry;
+import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory;
+import cz.msebera.android.httpclient.impl.client.DefaultHttpClient;
+import cz.msebera.android.httpclient.impl.conn.tsccm.ThreadSafeClientConnManager;
+import cz.msebera.android.httpclient.params.BasicHttpParams;
+import cz.msebera.android.httpclient.params.HttpParams;
+import cz.msebera.android.httpclient.params.HttpProtocolParams;
+import cz.msebera.android.httpclient.protocol.HTTP;
+
+import javax.net.ssl.*;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+/**
+ * This file is introduced to fix HTTPS Post bug on API < ICS see
+ * https://code.google.com/p/android/issues/detail?id=13117#c14
Warning! This omits SSL
+ * certificate validation on every device, use with caution
+ */
+public class MySSLSocketFactory extends SSLSocketFactory {
+ final SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ /**
+ * Creates a new SSL Socket Factory with the given KeyStore.
+ *
+ * @param truststore A KeyStore to create the SSL Socket Factory in context of
+ * @throws NoSuchAlgorithmException NoSuchAlgorithmException
+ * @throws KeyManagementException KeyManagementException
+ * @throws KeyStoreException KeyStoreException
+ * @throws UnrecoverableKeyException UnrecoverableKeyException
+ */
+ public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+ super(truststore);
+
+ X509TrustManager tm = new X509TrustManager() {
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ try {
+ chain[0].checkValidity();
+ } catch (Exception e) {
+ throw new CertificateException("Certificate not valid or trusted.");
+ }
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ try {
+ chain[0].checkValidity();
+ } catch (Exception e) {
+ throw new CertificateException("Certificate not valid or trusted.");
+ }
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ };
+
+ sslContext.init(null, new TrustManager[]{tm}, null);
+ }
+
+ /**
+ * Gets a KeyStore containing the Certificate
+ *
+ * @param cert InputStream of the Certificate
+ * @return KeyStore
+ */
+ public static KeyStore getKeystoreOfCA(InputStream cert) {
+
+ // Load CAs from an InputStream
+ InputStream caInput = null;
+ Certificate ca = null;
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ caInput = new BufferedInputStream(cert);
+ ca = cf.generateCertificate(caInput);
+ } catch (CertificateException e1) {
+ e1.printStackTrace();
+ } finally {
+ try {
+ if (caInput != null) {
+ caInput.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Create a KeyStore containing our trusted CAs
+ String keyStoreType = KeyStore.getDefaultType();
+ KeyStore keyStore = null;
+ try {
+ keyStore = KeyStore.getInstance(keyStoreType);
+ keyStore.load(null, null);
+ keyStore.setCertificateEntry("ca", ca);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return keyStore;
+ }
+
+ /**
+ * Gets a Default KeyStore
+ *
+ * @return KeyStore
+ */
+ public static KeyStore getKeystore() {
+ KeyStore trustStore = null;
+ try {
+ trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(null, null);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ return trustStore;
+ }
+
+ /**
+ * Returns a SSlSocketFactory which trusts all certificates
+ *
+ * @return SSLSocketFactory
+ */
+ public static SSLSocketFactory getFixedSocketFactory() {
+ SSLSocketFactory socketFactory;
+ try {
+ socketFactory = new MySSLSocketFactory(getKeystore());
+ socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ socketFactory = SSLSocketFactory.getSocketFactory();
+ }
+ return socketFactory;
+ }
+
+ /**
+ * Gets a DefaultHttpClient which trusts a set of certificates specified by the KeyStore
+ *
+ * @param keyStore custom provided KeyStore instance
+ * @return DefaultHttpClient
+ */
+ public static DefaultHttpClient getNewHttpClient(KeyStore keyStore) {
+
+ try {
+ SSLSocketFactory sf = new MySSLSocketFactory(keyStore);
+ SchemeRegistry registry = new SchemeRegistry();
+ registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ registry.register(new Scheme("https", sf, 443));
+
+ HttpParams params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
+
+ ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
+
+ return new DefaultHttpClient(ccm, params);
+ } catch (Exception e) {
+ return new DefaultHttpClient();
+ }
+ }
+
+ @Override
+ public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
+ Socket localSocket = sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
+ enableSecureProtocols(localSocket);
+ return localSocket;
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ Socket socket = sslContext.getSocketFactory().createSocket();
+ enableSecureProtocols(socket);
+ return socket;
+ }
+
+ /**
+ * Activate supported protocols on the socket.
+ *
+ * @param socket The socket on which to activate secure protocols.
+ */
+ private void enableSecureProtocols(Socket socket) {
+ // set all supported protocols
+ SSLParameters params = sslContext.getSupportedSSLParameters();
+ ((SSLSocket) socket).setEnabledProtocols(params.getProtocols());
+ }
+
+ /**
+ * Makes HttpsURLConnection trusts a set of certificates specified by the KeyStore
+ */
+ public void fixHttpsURLConnection() {
+ HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/PersistentCookieStore.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/PersistentCookieStore.java
new file mode 100644
index 0000000000000000000000000000000000000000..dfc770bee4284a2b71bdba3419c5c42eb0b7efe6
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/PersistentCookieStore.java
@@ -0,0 +1,259 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+
+import cz.msebera.android.httpclient.client.CookieStore;
+import cz.msebera.android.httpclient.cookie.Cookie;
+import ohos.app.Context;
+import ohos.data.DatabaseHelper;
+import ohos.data.preferences.Preferences;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A persistent cookie store which implements the Apache HttpClient {@link CookieStore} interface.
+ * Cookies are stored and will persist on the user's device between application sessions since they
+ * are serialized and stored in {@link Preferences}.
Instances of this class are
+ * designed to be used with {@link AsyncHttpClient#setCookieStore}, but can also be used with a
+ * regular old apache HttpClient/HttpContext if you prefer.
+ */
+public class PersistentCookieStore implements CookieStore {
+ private static final String LOG_TAG = "PersistentCookieStore";
+ private static final String COOKIE_PREFS = "CookiePrefsFile";
+ private static final String COOKIE_NAME_STORE = "names";
+ private static final String COOKIE_NAME_PREFIX = "cookie_";
+ private final ConcurrentHashMap cookies;
+ private final Preferences cookiePrefs;
+ private boolean omitNonPersistentCookies = false;
+
+ /**
+ * Construct a persistent cookie store.
+ *
+ * @param context Context to attach cookie store to
+ */
+ public PersistentCookieStore(Context context) {
+ DatabaseHelper helper=new DatabaseHelper(context);
+ cookiePrefs=helper.getPreferences("COOKIE_PREFS");
+// cookiePrefs = context.getSharedPreferences(COOKIE_PREFS, 0);
+ cookies = new ConcurrentHashMap();
+
+ // Load any previously stored cookies into the store
+ String storedCookieNames = cookiePrefs.getString(COOKIE_NAME_STORE, null);
+ if (storedCookieNames != null) {
+ String[] cookieNames = storedCookieNames.split( ",");
+ for (String name : cookieNames) {
+ String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX + name, null);
+ if (encodedCookie != null) {
+ Cookie decodedCookie = decodeCookie(encodedCookie);
+ if (decodedCookie != null) {
+ cookies.put(name, decodedCookie);
+ }
+ }
+ }
+
+ // Clear out expired cookies
+ clearExpired(new Date());
+ }
+ }
+
+ @Override
+ public void addCookie(Cookie cookie) {
+ if (omitNonPersistentCookies && !cookie.isPersistent())
+ return;
+ String name = cookie.getName() + cookie.getDomain();
+
+ // Save cookie into local store, or remove if expired
+ if (!cookie.isExpired(new Date())) {
+ cookies.put(name, cookie);
+ } else {
+ cookies.remove(name);
+ }
+
+ // Save cookie into persistent store
+// SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
+ cookiePrefs.putString(COOKIE_NAME_STORE, getKeySetString(cookies.keySet()));
+ cookiePrefs.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableCookie(cookie)));
+// prefsWriter.putString(COOKIE_NAME_STORE, TextUtils.join(",", cookies.keySet()));
+// prefsWriter.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableCookie(cookie)));
+ cookiePrefs.flush();
+ }
+
+ @Override
+ public void clear() {
+ // Clear cookies from persistent store
+// SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
+ for (String name : cookies.keySet()) {
+ cookiePrefs.delete(COOKIE_NAME_PREFIX + name);
+ }
+ cookiePrefs.delete(COOKIE_NAME_STORE);
+ cookiePrefs.flush();
+
+ // Clear cookies from local store
+ cookies.clear();
+ }
+
+ @Override
+ public boolean clearExpired(Date date) {
+ boolean clearedAny = false;
+// SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
+
+ for (ConcurrentHashMap.Entry entry : cookies.entrySet()) {
+ String name = entry.getKey();
+ Cookie cookie = entry.getValue();
+ if (cookie.isExpired(date)) {
+ // Clear cookies from local store
+ cookies.remove(name);
+
+ // Clear cookies from persistent store
+ cookiePrefs.delete(COOKIE_NAME_PREFIX + name);
+
+ // We've cleared at least one
+ clearedAny = true;
+ }
+ }
+
+ // Update names in persistent store
+ if (clearedAny) {
+ cookiePrefs.putString(COOKIE_NAME_STORE, getKeySetString(cookies.keySet()));
+ }
+ cookiePrefs.flush();
+
+ return clearedAny;
+ }
+
+ @Override
+ public List getCookies() {
+ return new ArrayList(cookies.values());
+ }
+
+ /**
+ * Will make PersistentCookieStore instance ignore Cookies, which are non-persistent by
+ * signature (`Cookie.isPersistent`)
+ *
+ * @param omitNonPersistentCookies true if non-persistent cookies should be omited
+ */
+ public void setOmitNonPersistentCookies(boolean omitNonPersistentCookies) {
+ this.omitNonPersistentCookies = omitNonPersistentCookies;
+ }
+
+ /**
+ * Non-standard helper method, to delete cookie
+ *
+ * @param cookie cookie to be removed
+ */
+ public void deleteCookie(Cookie cookie) {
+ String name = cookie.getName() + cookie.getDomain();
+ cookies.remove(name);
+// SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
+ cookiePrefs.delete(COOKIE_NAME_PREFIX + name);
+ cookiePrefs.flush();
+// prefsWriter.apply();
+ }
+
+ /**
+ * Serializes Cookie object into String
+ *
+ * @param cookie cookie to be encoded, can be null
+ * @return cookie encoded as String
+ */
+ protected String encodeCookie(SerializableCookie cookie) {
+ if (cookie == null)
+ return null;
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ try {
+ ObjectOutputStream outputStream = new ObjectOutputStream(os);
+ outputStream.writeObject(cookie);
+ } catch (IOException e) {
+ AsyncHttpClient.log.d(LOG_TAG, "IOException in encodeCookie", e);
+ return null;
+ }
+
+ return byteArrayToHexString(os.toByteArray());
+ }
+
+ /**
+ * Returns cookie decoded from cookie string
+ *
+ * @param cookieString string of cookie as returned from http request
+ * @return decoded cookie or null if exception occured
+ */
+ protected Cookie decodeCookie(String cookieString) {
+ byte[] bytes = hexStringToByteArray(cookieString);
+ ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
+ Cookie cookie = null;
+ try {
+ ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
+ cookie = ((SerializableCookie) objectInputStream.readObject()).getCookie();
+ } catch (IOException e) {
+ AsyncHttpClient.log.d(LOG_TAG, "IOException in decodeCookie", e);
+ } catch (ClassNotFoundException e) {
+ AsyncHttpClient.log.d(LOG_TAG, "ClassNotFoundException in decodeCookie", e);
+ }
+
+ return cookie;
+ }
+
+ /**
+ * Using some super basic byte array <-> hex conversions so we don't have to rely on any
+ * large Base64 libraries. Can be overridden if you like!
+ *
+ * @param bytes byte array to be converted
+ * @return string containing hex values
+ */
+ protected String byteArrayToHexString(byte[] bytes) {
+ StringBuilder sb = new StringBuilder(bytes.length * 2);
+ for (byte element : bytes) {
+ int v = element & 0xff;
+ if (v < 16) {
+ sb.append('0');
+ }
+ sb.append(Integer.toHexString(v));
+ }
+ return sb.toString().toUpperCase(Locale.US);
+ }
+
+ /**
+ * Converts hex values from strings to byte arra
+ *
+ * @param hexString string of hex-encoded values
+ * @return decoded byte array
+ */
+ protected byte[] hexStringToByteArray(String hexString) {
+ int len = hexString.length();
+ byte[] data = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i + 1), 16));
+ }
+ return data;
+ }
+
+
+ private String getKeySetString(Setkeyset){
+ IteratorstringIterator=keyset.iterator();
+ StringBuffer stringBuffer=new StringBuffer();
+ while (stringIterator.hasNext()){
+ stringBuffer.append(stringIterator.next()).append(",");
+ }
+ String key=stringBuffer.substring(0,stringBuffer.length()-1);
+ return key;
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/PreemptiveAuthorizationHttpRequestInterceptor.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/PreemptiveAuthorizationHttpRequestInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b163aa59ddf8c72f8ae7bbca499f96015b0d7693
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/PreemptiveAuthorizationHttpRequestInterceptor.java
@@ -0,0 +1,54 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2014 Marek Sebera
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.HttpException;
+import cz.msebera.android.httpclient.HttpHost;
+import cz.msebera.android.httpclient.HttpRequest;
+import cz.msebera.android.httpclient.HttpRequestInterceptor;
+import cz.msebera.android.httpclient.auth.AuthScope;
+import cz.msebera.android.httpclient.auth.AuthState;
+import cz.msebera.android.httpclient.auth.Credentials;
+import cz.msebera.android.httpclient.client.CredentialsProvider;
+import cz.msebera.android.httpclient.client.protocol.ClientContext;
+import cz.msebera.android.httpclient.impl.auth.BasicScheme;
+import cz.msebera.android.httpclient.protocol.ExecutionContext;
+import cz.msebera.android.httpclient.protocol.HttpContext;
+
+import java.io.IOException;
+
+public class PreemptiveAuthorizationHttpRequestInterceptor implements HttpRequestInterceptor {
+
+ public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+ AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
+ CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
+ ClientContext.CREDS_PROVIDER);
+ HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+
+ if (authState.getAuthScheme() == null) {
+ AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
+ Credentials creds = credsProvider.getCredentials(authScope);
+ if (creds != null) {
+ authState.setAuthScheme(new BasicScheme());
+ authState.setCredentials(creds);
+ }
+ }
+ }
+
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RangeFileAsyncHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RangeFileAsyncHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..21964c091ceaf509543c6c4accd625b10337dbea
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RangeFileAsyncHttpResponseHandler.java
@@ -0,0 +1,105 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2014 Marek Sebera
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.*;
+import cz.msebera.android.httpclient.client.HttpResponseException;
+import cz.msebera.android.httpclient.client.methods.HttpUriRequest;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+public abstract class RangeFileAsyncHttpResponseHandler extends FileAsyncHttpResponseHandler {
+ private static final String LOG_TAG = "RangeFileAsyncHttpRH";
+
+ private long current = 0;
+ private boolean append = false;
+
+ /**
+ * Obtains new RangeFileAsyncHttpResponseHandler and stores response in passed file
+ *
+ * @param file File to store response within, must not be null
+ */
+ public RangeFileAsyncHttpResponseHandler(File file) {
+ super(file);
+ }
+
+ @Override
+ public void sendResponseMessage(HttpResponse response) throws IOException {
+ if (!Thread.currentThread().isInterrupted()) {
+ StatusLine status = response.getStatusLine();
+ if (status.getStatusCode() == HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE) {
+ //already finished
+ if (!Thread.currentThread().isInterrupted())
+ sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(), null);
+ } else if (status.getStatusCode() >= 300) {
+ if (!Thread.currentThread().isInterrupted())
+ sendFailureMessage(status.getStatusCode(), response.getAllHeaders(), null, new HttpResponseException(status.getStatusCode(), status.getReasonPhrase()));
+ } else {
+ if (!Thread.currentThread().isInterrupted()) {
+ Header header = response.getFirstHeader(AsyncHttpClient.HEADER_CONTENT_RANGE);
+ if (header == null) {
+ append = false;
+ current = 0;
+ } else {
+ AsyncHttpClient.log.v(LOG_TAG, AsyncHttpClient.HEADER_CONTENT_RANGE + ": " + header.getValue());
+ }
+ sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(), getResponseData(response.getEntity()));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected byte[] getResponseData(HttpEntity entity) throws IOException {
+ if (entity != null) {
+ InputStream instream = entity.getContent();
+ long contentLength = entity.getContentLength() + current;
+ FileOutputStream buffer = new FileOutputStream(getTargetFile(), append);
+ if (instream != null) {
+ try {
+ byte[] tmp = new byte[BUFFER_SIZE];
+ int l;
+ while (current < contentLength && (l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) {
+ current += l;
+ buffer.write(tmp, 0, l);
+ sendProgressMessage(current, contentLength);
+ }
+ } finally {
+ instream.close();
+ buffer.flush();
+ buffer.close();
+ }
+ }
+ }
+ return null;
+ }
+
+ public void updateRequestHeaders(HttpUriRequest uriRequest) {
+ if (file.exists() && file.canWrite())
+ current = file.length();
+ if (current > 0) {
+ append = true;
+ uriRequest.setHeader("Range", "bytes=" + current + "-");
+ }
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RequestHandle.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RequestHandle.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb714f5b10333fe1116ae02219479805231ad733
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RequestHandle.java
@@ -0,0 +1,121 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2013 Jason Choy
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import ohos.eventhandler.EventRunner;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * A Handle to an AsyncRequest which can be used to cancel a running request.
+ */
+public class RequestHandle {
+ private final WeakReference request;
+
+ public RequestHandle(AsyncHttpRequest request) {
+ this.request = new WeakReference(request);
+ }
+
+ /**
+ * Attempts to cancel this request. This attempt will fail if the request has already completed,
+ * has already been cancelled, or could not be cancelled for some other reason. If successful,
+ * and this request has not started when cancel is called, this request should never run. If the
+ * request has already started, then the mayInterruptIfRunning parameter determines whether the
+ * thread executing this request should be interrupted in an attempt to stop the request.
+ *
After this method returns, subsequent calls to isDone() will always return
+ * true. Subsequent calls to isCancelled() will always return true if this method returned
+ * true. Subsequent calls to isDone() will return true either if the request got cancelled by
+ * this method, or if the request completed normally
+ *
+ * @param mayInterruptIfRunning true if the thread executing this request should be interrupted;
+ * otherwise, in-progress requests are allowed to complete
+ * @return false if the request could not be cancelled, typically because it has already
+ * completed normally; true otherwise
+ */
+ public boolean cancel(final boolean mayInterruptIfRunning) {
+ final AsyncHttpRequest _request = request.get();
+ if (_request != null) {
+ if (EventRunner.current() == EventRunner.getMainEventRunner()) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ _request.cancel(mayInterruptIfRunning);
+ }
+ }).start();
+ // Cannot reliably tell if the request got immediately canceled at this point
+ // we'll assume it got cancelled
+ return true;
+ } else {
+ return _request.cancel(mayInterruptIfRunning);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if this task completed. Completion may be due to normal termination, an
+ * exception, or cancellation -- in all of these cases, this method will return true.
+ *
+ * @return true if this task completed
+ */
+ public boolean isFinished() {
+ AsyncHttpRequest _request = request.get();
+ return _request == null || _request.isDone();
+ }
+
+ /**
+ * Returns true if this task was cancelled before it completed normally.
+ *
+ * @return true if this task was cancelled before it completed
+ */
+ public boolean isCancelled() {
+ AsyncHttpRequest _request = request.get();
+ return _request == null || _request.isCancelled();
+ }
+
+ public boolean shouldBeGarbageCollected() {
+ boolean should = isCancelled() || isFinished();
+ if (should)
+ request.clear();
+ return should;
+ }
+
+ /**
+ * Will return TAG of underlying AsyncHttpRequest if it's not already GCed
+ *
+ * @return Object TAG, can be null
+ */
+ public Object getTag() {
+ AsyncHttpRequest _request = request.get();
+ return _request == null ? null : _request.getTag();
+ }
+
+ /**
+ * Will set Object as TAG to underlying AsyncHttpRequest
+ *
+ * @param tag Object used as TAG to underlying AsyncHttpRequest
+ * @return this RequestHandle to allow fluid syntax
+ */
+ public RequestHandle setTag(Object tag) {
+ AsyncHttpRequest _request = request.get();
+ if (_request != null)
+ _request.setRequestTag(tag);
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RequestParams.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RequestParams.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f0badcff79cca1dffc38eb50267b8641ebde638
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RequestParams.java
@@ -0,0 +1,693 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.HttpEntity;
+import cz.msebera.android.httpclient.client.entity.UrlEncodedFormEntity;
+import cz.msebera.android.httpclient.client.utils.URLEncodedUtils;
+import cz.msebera.android.httpclient.message.BasicNameValuePair;
+import cz.msebera.android.httpclient.protocol.HTTP;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+//import java.util.concurrent.ConcurrentSkipList;
+
+/**
+ * A collection of string request parameters or files to send along with requests made from an
+ * {@link AsyncHttpClient} instance.
For example:
+ *
+ * RequestParams params = new RequestParams();
+ * params.put("username", "james");
+ * params.put("password", "123456");
+ * params.put("email", "my@email.com");
+ * params.put("profile_picture", new File("pic.jpg")); // Upload a File
+ * params.put("profile_picture2", someInputStream); // Upload an InputStream
+ * params.put("profile_picture3", new ByteArrayInputStream(someBytes)); // Upload some bytes
+ *
+ * Map<String, String> map = new HashMap<String, String>();
+ * map.put("first_name", "James");
+ * map.put("last_name", "Smith");
+ * params.put("user", map); // url params: "user[first_name]=James&user[last_name]=Smith"
+ *
+ * Set<String> set = new HashSet<String>(); // unordered collection
+ * set.add("music");
+ * set.add("art");
+ * params.put("like", set); // url params: "like=music&like=art"
+ *
+ * List<String> list = new ArrayList<String>(); // Ordered collection
+ * list.add("Java");
+ * list.add("C");
+ * params.put("languages", list); // url params: "languages[0]=Java&languages[1]=C"
+ *
+ * String[] colors = { "blue", "yellow" }; // Ordered collection
+ * params.put("colors", colors); // url params: "colors[0]=blue&colors[1]=yellow"
+ *
+ * File[] files = { new File("pic.jpg"), new File("pic1.jpg") }; // Ordered collection
+ * params.put("files", files); // url params: "files[]=pic.jpg&files[]=pic1.jpg"
+ *
+ * List<Map<String, String>> listOfMaps = new ArrayList<Map<String,
+ * String>>();
+ * Map<String, String> user1 = new HashMap<String, String>();
+ * user1.put("age", "30");
+ * user1.put("gender", "male");
+ * Map<String, String> user2 = new HashMap<String, String>();
+ * user2.put("age", "25");
+ * user2.put("gender", "female");
+ * listOfMaps.add(user1);
+ * listOfMaps.add(user2);
+ * params.put("users", listOfMaps); // url params: "users[][age]=30&users[][gender]=male&users[][age]=25&users[][gender]=female"
+ *
+ * AsyncHttpClient client = new AsyncHttpClient();
+ * client.post("https://myendpoint.com", params, responseHandler);
+ *
+ */
+public class RequestParams implements Serializable {
+
+ public final static String APPLICATION_OCTET_STREAM =
+ "application/octet-stream";
+
+ public final static String APPLICATION_JSON =
+ "application/json";
+
+ protected final static String LOG_TAG = "RequestParams";
+ protected final ConcurrentSkipListMap urlParams = new ConcurrentSkipListMap();
+ protected final ConcurrentSkipListMap streamParams = new ConcurrentSkipListMap();
+ protected final ConcurrentSkipListMap fileParams = new ConcurrentSkipListMap();
+ protected final ConcurrentSkipListMap> fileArrayParams = new ConcurrentSkipListMap>();
+ protected final ConcurrentSkipListMap urlParamsWithObjects = new ConcurrentSkipListMap();
+ protected boolean isRepeatable;
+ protected boolean forceMultipartEntity = false;
+ protected boolean useJsonStreamer;
+ protected String elapsedFieldInJsonStreamer = "_elapsed";
+ protected boolean autoCloseInputStreams;
+ protected String contentEncoding = HTTP.UTF_8;
+
+ /**
+ * Constructs a new empty {@code RequestParams} instance.
+ */
+ public RequestParams() {
+ this((Map) null);
+ }
+
+ /**
+ * Constructs a new RequestParams instance containing the key/value string params from the
+ * specified map.
+ *
+ * @param source the source key/value string map to add.
+ */
+ public RequestParams(Map source) {
+ if (source != null) {
+ for (Map.Entry entry : source.entrySet()) {
+ put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ /**
+ * Constructs a new RequestParams instance and populate it with a single initial key/value
+ * string param.
+ *
+ * @param key the key name for the intial param.
+ * @param value the value string for the initial param.
+ */
+ public RequestParams(final String key, final String value) {
+ this(new HashMap() {{
+ put(key, value);
+ }});
+ }
+
+ /**
+ * Constructs a new RequestParams instance and populate it with multiple initial key/value
+ * string param.
+ *
+ * @param keysAndValues a sequence of keys and values. Objects are automatically converted to
+ * Strings (including the value {@code null}).
+ * @throws IllegalArgumentException if the number of arguments isn't even.
+ */
+ public RequestParams(Object... keysAndValues) {
+ int len = keysAndValues.length;
+ if (len % 2 != 0)
+ throw new IllegalArgumentException("Supplied arguments must be even");
+ for (int i = 0; i < len; i += 2) {
+ String key = String.valueOf(keysAndValues[i]);
+ String val = String.valueOf(keysAndValues[i + 1]);
+ put(key, val);
+ }
+ }
+
+ /**
+ * Sets content encoding for return value of {@link #getParamString()} and {@link
+ * #createFormEntity()}
Default encoding is "UTF-8"
+ *
+ * @param encoding String constant from {@link HTTP}
+ */
+ public void setContentEncoding(final String encoding) {
+ if (encoding != null) {
+ this.contentEncoding = encoding;
+ } else {
+ AsyncHttpClient.log.d(LOG_TAG, "setContentEncoding called with null attribute");
+ }
+ }
+
+ /**
+ * If set to true will force Content-Type header to `multipart/form-data`
+ * even if there are not Files or Streams to be send
+ *
+ * Default value is false
+ *
+ * @param force boolean, should declare content-type multipart/form-data even without files or streams present
+ */
+ public void setForceMultipartEntityContentType(boolean force) {
+ this.forceMultipartEntity = force;
+ }
+
+ /**
+ * Adds a key/value string pair to the request.
+ *
+ * @param key the key name for the new param.
+ * @param value the value string for the new param.
+ */
+ public void put(String key, String value) {
+ if (key != null && value != null) {
+ urlParams.put(key, value);
+ }
+ }
+
+ /**
+ * Adds files array to the request.
+ *
+ * @param key the key name for the new param.
+ * @param files the files array to add.
+ * @throws FileNotFoundException if one of passed files is not found at time of assembling the requestparams into request
+ */
+ public void put(String key, File files[]) throws FileNotFoundException {
+ put(key, files, null, null);
+ }
+
+ /**
+ * Adds files array to the request with both custom provided file content-type and files name
+ *
+ * @param key the key name for the new param.
+ * @param files the files array to add.
+ * @param contentType the content type of the file, eg. application/json
+ * @param customFileName file name to use instead of real file name
+ * @throws FileNotFoundException throws if wrong File argument was passed
+ */
+ public void put(String key, File files[], String contentType, String customFileName) throws FileNotFoundException {
+
+ if (key != null) {
+ List fileWrappers = new ArrayList();
+ for (File file : files) {
+ if (file == null || !file.exists()) {
+ throw new FileNotFoundException();
+ }
+ fileWrappers.add(new FileWrapper(file, contentType, customFileName));
+ }
+ fileArrayParams.put(key, fileWrappers);
+ }
+ }
+
+ /**
+ * Adds a file to the request.
+ *
+ * @param key the key name for the new param.
+ * @param file the file to add.
+ * @throws FileNotFoundException throws if wrong File argument was passed
+ */
+ public void put(String key, File file) throws FileNotFoundException {
+ put(key, file, null, null);
+ }
+
+ /**
+ * Adds a file to the request with custom provided file name
+ *
+ * @param key the key name for the new param.
+ * @param file the file to add.
+ * @param customFileName file name to use instead of real file name
+ * @throws FileNotFoundException throws if wrong File argument was passed
+ */
+ public void put(String key, String customFileName, File file) throws FileNotFoundException {
+ put(key, file, null, customFileName);
+ }
+
+ /**
+ * Adds a file to the request with custom provided file content-type
+ *
+ * @param key the key name for the new param.
+ * @param file the file to add.
+ * @param contentType the content type of the file, eg. application/json
+ * @throws FileNotFoundException throws if wrong File argument was passed
+ */
+ public void put(String key, File file, String contentType) throws FileNotFoundException {
+ put(key, file, contentType, null);
+ }
+
+ /**
+ * Adds a file to the request with both custom provided file content-type and file name
+ *
+ * @param key the key name for the new param.
+ * @param file the file to add.
+ * @param contentType the content type of the file, eg. application/json
+ * @param customFileName file name to use instead of real file name
+ * @throws FileNotFoundException throws if wrong File argument was passed
+ */
+ public void put(String key, File file, String contentType, String customFileName) throws FileNotFoundException {
+ if (file == null || !file.exists()) {
+ throw new FileNotFoundException();
+ }
+ if (key != null) {
+ fileParams.put(key, new FileWrapper(file, contentType, customFileName));
+ }
+ }
+
+ /**
+ * Adds an input stream to the request.
+ *
+ * @param key the key name for the new param.
+ * @param stream the input stream to add.
+ */
+ public void put(String key, InputStream stream) {
+ put(key, stream, null);
+ }
+
+ /**
+ * Adds an input stream to the request.
+ *
+ * @param key the key name for the new param.
+ * @param stream the input stream to add.
+ * @param name the name of the stream.
+ */
+ public void put(String key, InputStream stream, String name) {
+ put(key, stream, name, null);
+ }
+
+ /**
+ * Adds an input stream to the request.
+ *
+ * @param key the key name for the new param.
+ * @param stream the input stream to add.
+ * @param name the name of the stream.
+ * @param contentType the content type of the file, eg. application/json
+ */
+ public void put(String key, InputStream stream, String name, String contentType) {
+ put(key, stream, name, contentType, autoCloseInputStreams);
+ }
+
+ /**
+ * Adds an input stream to the request.
+ *
+ * @param key the key name for the new param.
+ * @param stream the input stream to add.
+ * @param name the name of the stream.
+ * @param contentType the content type of the file, eg. application/json
+ * @param autoClose close input stream automatically on successful upload
+ */
+ public void put(String key, InputStream stream, String name, String contentType, boolean autoClose) {
+ if (key != null && stream != null) {
+ streamParams.put(key, StreamWrapper.newInstance(stream, name, contentType, autoClose));
+ }
+ }
+
+ /**
+ * Adds param with non-string value (e.g. Map, List, Set).
+ *
+ * @param key the key name for the new param.
+ * @param value the non-string value object for the new param.
+ */
+ public void put(String key, Object value) {
+ if (key != null && value != null) {
+ urlParamsWithObjects.put(key, value);
+ }
+ }
+
+ /**
+ * Adds a int value to the request.
+ *
+ * @param key the key name for the new param.
+ * @param value the value int for the new param.
+ */
+ public void put(String key, int value) {
+ if (key != null) {
+ urlParams.put(key, String.valueOf(value));
+ }
+ }
+
+ /**
+ * Adds a long value to the request.
+ *
+ * @param key the key name for the new param.
+ * @param value the value long for the new param.
+ */
+ public void put(String key, long value) {
+ if (key != null) {
+ urlParams.put(key, String.valueOf(value));
+ }
+ }
+
+ /**
+ * Adds string value to param which can have more than one value.
+ *
+ * @param key the key name for the param, either existing or new.
+ * @param value the value string for the new param.
+ */
+ public void add(String key, String value) {
+ if (key != null && value != null) {
+ Object params = urlParamsWithObjects.get(key);
+ if (params == null) {
+ // Backward compatible, which will result in "k=v1&k=v2&k=v3"
+ params = new HashSet();
+ this.put(key, params);
+ }
+ if (params instanceof List) {
+ ((List) params).add(value);
+ } else if (params instanceof Set) {
+ ((Set) params).add(value);
+ }
+ }
+ }
+
+ /**
+ * Removes a parameter from the request.
+ *
+ * @param key the key name for the parameter to remove.
+ */
+ public void remove(String key) {
+ urlParams.remove(key);
+ streamParams.remove(key);
+ fileParams.remove(key);
+ urlParamsWithObjects.remove(key);
+ fileArrayParams.remove(key);
+ }
+
+ /**
+ * Check if a parameter is defined.
+ *
+ * @param key the key name for the parameter to check existence.
+ * @return Boolean
+ */
+ public boolean has(String key) {
+ return urlParams.get(key) != null ||
+ streamParams.get(key) != null ||
+ fileParams.get(key) != null ||
+ urlParamsWithObjects.get(key) != null ||
+ fileArrayParams.get(key) != null;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ for (ConcurrentSkipListMap.Entry entry : urlParams.entrySet()) {
+ if (result.length() > 0)
+ result.append("&");
+
+ result.append(entry.getKey());
+ result.append("=");
+ result.append(entry.getValue());
+ }
+
+ for (ConcurrentSkipListMap.Entry entry : streamParams.entrySet()) {
+ if (result.length() > 0)
+ result.append("&");
+
+ result.append(entry.getKey());
+ result.append("=");
+ result.append("STREAM");
+ }
+
+ for (ConcurrentSkipListMap.Entry entry : fileParams.entrySet()) {
+ if (result.length() > 0)
+ result.append("&");
+
+ result.append(entry.getKey());
+ result.append("=");
+ result.append("FILE");
+ }
+
+ for (ConcurrentSkipListMap.Entry> entry : fileArrayParams.entrySet()) {
+ if (result.length() > 0)
+ result.append("&");
+
+ result.append(entry.getKey());
+ result.append("=");
+ result.append("FILES(SIZE=").append(entry.getValue().size()).append(")");
+ }
+
+ List params = getParamsList(null, urlParamsWithObjects);
+ for (BasicNameValuePair kv : params) {
+ if (result.length() > 0)
+ result.append("&");
+
+ result.append(kv.getName());
+ result.append("=");
+ result.append(kv.getValue());
+ }
+
+ return result.toString();
+ }
+
+ public void setHttpEntityIsRepeatable(boolean flag) {
+ this.isRepeatable = flag;
+ }
+
+ public void setUseJsonStreamer(boolean flag) {
+ this.useJsonStreamer = flag;
+ }
+
+ /**
+ * Sets an additional field when upload a JSON object through the streamer
+ * to hold the time, in milliseconds, it took to upload the payload. By
+ * default, this field is set to "_elapsed".
+ *
+ * To disable this feature, call this method with null as the field value.
+ *
+ * @param value field name to add elapsed time, or null to disable
+ */
+ public void setElapsedFieldInJsonStreamer(String value) {
+ this.elapsedFieldInJsonStreamer = value;
+ }
+
+ /**
+ * Set global flag which determines whether to automatically close input streams on successful
+ * upload.
+ *
+ * @param flag boolean whether to automatically close input streams
+ */
+ public void setAutoCloseInputStreams(boolean flag) {
+ autoCloseInputStreams = flag;
+ }
+
+ /**
+ * Returns an HttpEntity containing all request parameters.
+ *
+ * @param progressHandler HttpResponseHandler for reporting progress on entity submit
+ * @return HttpEntity resulting HttpEntity to be included along with {@link
+ * cz.msebera.android.httpclient.client.methods.HttpEntityEnclosingRequestBase}
+ * @throws IOException if one of the streams cannot be read
+ */
+ public HttpEntity getEntity(ResponseHandlerInterface progressHandler) throws IOException {
+ if (useJsonStreamer) {
+ return createJsonStreamerEntity(progressHandler);
+ } else if (!forceMultipartEntity && streamParams.isEmpty() && fileParams.isEmpty() && fileArrayParams.isEmpty()) {
+ return createFormEntity();
+ } else {
+ return createMultipartEntity(progressHandler);
+ }
+ }
+
+ private HttpEntity createJsonStreamerEntity(ResponseHandlerInterface progressHandler) throws IOException {
+ JsonStreamerEntity entity = new JsonStreamerEntity(
+ progressHandler,
+ !fileParams.isEmpty() || !streamParams.isEmpty(),
+ elapsedFieldInJsonStreamer);
+
+ // Add string params
+ for (ConcurrentSkipListMap.Entry entry : urlParams.entrySet()) {
+ entity.addPart(entry.getKey(), entry.getValue());
+ }
+
+ // Add non-string params
+ for (ConcurrentSkipListMap.Entry entry : urlParamsWithObjects.entrySet()) {
+ entity.addPart(entry.getKey(), entry.getValue());
+ }
+
+ // Add file params
+ for (ConcurrentSkipListMap.Entry entry : fileParams.entrySet()) {
+ entity.addPart(entry.getKey(), entry.getValue());
+ }
+
+ // Add stream params
+ for (ConcurrentSkipListMap.Entry entry : streamParams.entrySet()) {
+ StreamWrapper stream = entry.getValue();
+ if (stream.inputStream != null) {
+ entity.addPart(entry.getKey(),
+ StreamWrapper.newInstance(
+ stream.inputStream,
+ stream.name,
+ stream.contentType,
+ stream.autoClose)
+ );
+ }
+ }
+
+ return entity;
+ }
+
+ private HttpEntity createFormEntity() {
+ try {
+ return new UrlEncodedFormEntity(getParamsList(), contentEncoding);
+ } catch (UnsupportedEncodingException e) {
+ AsyncHttpClient.log.e(LOG_TAG, "createFormEntity failed", e);
+ return null; // Can happen, if the 'contentEncoding' won't be HTTP.UTF_8
+ }
+ }
+
+ private HttpEntity createMultipartEntity(ResponseHandlerInterface progressHandler) throws IOException {
+ SimpleMultipartEntity entity = new SimpleMultipartEntity(progressHandler);
+ entity.setIsRepeatable(isRepeatable);
+
+ // Add string params
+ for (ConcurrentSkipListMap.Entry entry : urlParams.entrySet()) {
+ entity.addPartWithCharset(entry.getKey(), entry.getValue(), contentEncoding);
+ }
+
+ // Add non-string params
+ List params = getParamsList(null, urlParamsWithObjects);
+ for (BasicNameValuePair kv : params) {
+ entity.addPartWithCharset(kv.getName(), kv.getValue(), contentEncoding);
+ }
+
+ // Add stream params
+ for (ConcurrentSkipListMap.Entry entry : streamParams.entrySet()) {
+ StreamWrapper stream = entry.getValue();
+ if (stream.inputStream != null) {
+ entity.addPart(entry.getKey(), stream.name, stream.inputStream,
+ stream.contentType);
+ }
+ }
+
+ // Add file params
+ for (ConcurrentSkipListMap.Entry entry : fileParams.entrySet()) {
+ FileWrapper fileWrapper = entry.getValue();
+ entity.addPart(entry.getKey(), fileWrapper.file, fileWrapper.contentType, fileWrapper.customFileName);
+ }
+
+ // Add file collection
+ for (ConcurrentSkipListMap.Entry> entry : fileArrayParams.entrySet()) {
+ List fileWrapper = entry.getValue();
+ for (FileWrapper fw : fileWrapper) {
+ entity.addPart(entry.getKey(), fw.file, fw.contentType, fw.customFileName);
+ }
+ }
+
+ return entity;
+ }
+
+ protected List getParamsList() {
+ List lparams = new LinkedList();
+
+ for (ConcurrentSkipListMap.Entry entry : urlParams.entrySet()) {
+ lparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+ }
+
+ lparams.addAll(getParamsList(null, urlParamsWithObjects));
+
+ return lparams;
+ }
+
+ private List getParamsList(String key, Object value) {
+ List params = new LinkedList();
+ if (value instanceof Map) {
+ Map map = (Map) value;
+ List list = new ArrayList(map.keySet());
+ // Ensure consistent ordering in query string
+ if (list.size() > 0 && list.get(0) instanceof Comparable) {
+ Collections.sort(list);
+ }
+ for (Object nestedKey : list) {
+ if (nestedKey instanceof String) {
+ Object nestedValue = map.get(nestedKey);
+ if (nestedValue != null) {
+ params.addAll(getParamsList(key == null ? (String) nestedKey : String.format(Locale.US, "%s[%s]", key, nestedKey),
+ nestedValue));
+ }
+ }
+ }
+ } else if (value instanceof List) {
+ List list = (List) value;
+ int listSize = list.size();
+ for (int nestedValueIndex = 0; nestedValueIndex < listSize; nestedValueIndex++) {
+ params.addAll(getParamsList(String.format(Locale.US, "%s[%d]", key, nestedValueIndex), list.get(nestedValueIndex)));
+ }
+ } else if (value instanceof Object[]) {
+ Object[] array = (Object[]) value;
+ int arrayLength = array.length;
+ for (int nestedValueIndex = 0; nestedValueIndex < arrayLength; nestedValueIndex++) {
+ params.addAll(getParamsList(String.format(Locale.US, "%s[%d]", key, nestedValueIndex), array[nestedValueIndex]));
+ }
+ } else if (value instanceof Set) {
+ Set set = (Set) value;
+ for (Object nestedValue : set) {
+ params.addAll(getParamsList(key, nestedValue));
+ }
+ } else {
+ params.add(new BasicNameValuePair(key, value.toString()));
+ }
+ return params;
+ }
+
+ protected String getParamString() {
+ return URLEncodedUtils.format(getParamsList(), contentEncoding);
+ }
+
+ public static class FileWrapper implements Serializable {
+ public final File file;
+ public final String contentType;
+ public final String customFileName;
+
+ public FileWrapper(File file, String contentType, String customFileName) {
+ this.file = file;
+ this.contentType = contentType;
+ this.customFileName = customFileName;
+ }
+ }
+
+ public static class StreamWrapper {
+ public final InputStream inputStream;
+ public final String name;
+ public final String contentType;
+ public final boolean autoClose;
+
+ public StreamWrapper(InputStream inputStream, String name, String contentType, boolean autoClose) {
+ this.inputStream = inputStream;
+ this.name = name;
+ this.contentType = contentType;
+ this.autoClose = autoClose;
+ }
+
+ static StreamWrapper newInstance(InputStream inputStream, String name, String contentType, boolean autoClose) {
+ return new StreamWrapper(
+ inputStream,
+ name,
+ contentType == null ? APPLICATION_OCTET_STREAM : contentType,
+ autoClose);
+ }
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/ResponseHandlerInterface.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/ResponseHandlerInterface.java
new file mode 100644
index 0000000000000000000000000000000000000000..820906ff7d58d320e59467c50fdb327a17543537
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/ResponseHandlerInterface.java
@@ -0,0 +1,189 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2013 Marek Sebera
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpResponse;
+
+import java.io.IOException;
+import java.net.URI;
+
+/**
+ * Interface to standardize implementations
+ */
+public interface ResponseHandlerInterface {
+
+ /**
+ * Returns data whether request completed successfully
+ *
+ * @param response HttpResponse object with data
+ * @throws IOException if retrieving data from response fails
+ */
+ void sendResponseMessage(HttpResponse response) throws IOException;
+
+ /**
+ * Notifies callback, that request started execution
+ */
+ void sendStartMessage();
+
+ /**
+ * Notifies callback, that request was completed and is being removed from thread pool
+ */
+ void sendFinishMessage();
+
+ /**
+ * Notifies callback, that request (mainly uploading) has progressed
+ *
+ * @param bytesWritten number of written bytes
+ * @param bytesTotal number of total bytes to be written
+ */
+ void sendProgressMessage(long bytesWritten, long bytesTotal);
+
+ /**
+ * Notifies callback, that request was cancelled
+ */
+ void sendCancelMessage();
+
+ /**
+ * Notifies callback, that request was handled successfully
+ *
+ * @param statusCode HTTP status code
+ * @param headers returned headers
+ * @param responseBody returned data
+ */
+ void sendSuccessMessage(int statusCode, Header[] headers, byte[] responseBody);
+
+ /**
+ * Returns if request was completed with error code or failure of implementation
+ *
+ * @param statusCode returned HTTP status code
+ * @param headers returned headers
+ * @param responseBody returned data
+ * @param error cause of request failure
+ */
+ void sendFailureMessage(int statusCode, Header[] headers, byte[] responseBody, Throwable error);
+
+ /**
+ * Notifies callback of retrying request
+ *
+ * @param retryNo number of retry within one request
+ */
+ void sendRetryMessage(int retryNo);
+
+ /**
+ * Returns URI which was used to request
+ *
+ * @return uri of origin request
+ */
+ URI getRequestURI();
+
+ /**
+ * Helper for handlers to receive Request URI info
+ *
+ * @param requestURI claimed request URI
+ */
+ void setRequestURI(URI requestURI);
+
+ /**
+ * Returns Header[] which were used to request
+ *
+ * @return headers from origin request
+ */
+ Header[] getRequestHeaders();
+
+ /**
+ * Helper for handlers to receive Request Header[] info
+ *
+ * @param requestHeaders Headers, claimed to be from original request
+ */
+ void setRequestHeaders(Header[] requestHeaders);
+
+ /**
+ * Returns whether the handler is asynchronous or synchronous
+ *
+ * @return boolean if the ResponseHandler is running in synchronous mode
+ */
+ boolean getUseSynchronousMode();
+
+ /**
+ * Can set, whether the handler should be asynchronous or synchronous
+ *
+ * @param useSynchronousMode whether data should be handled on background Thread on UI Thread
+ */
+ void setUseSynchronousMode(boolean useSynchronousMode);
+
+ /**
+ * Returns whether the handler should be executed on the pool's thread
+ * or the UI thread
+ *
+ * @return boolean if the ResponseHandler should run on pool's thread
+ */
+ boolean getUsePoolThread();
+
+ /**
+ * Sets whether the handler should be executed on the pool's thread or the
+ * UI thread
+ *
+ * @param usePoolThread if the ResponseHandler should run on pool's thread
+ */
+ void setUsePoolThread(boolean usePoolThread);
+
+ /**
+ * This method is called once by the system when the response is about to be
+ * processed by the system. The library makes sure that a single response
+ * is pre-processed only once.
+ *
+ * Please note: pre-processing does NOT run on the main thread, and thus
+ * any UI activities that you must perform should be properly dispatched to
+ * the app's UI thread.
+ *
+ * @param instance An instance of this response object
+ * @param response The response to pre-processed
+ */
+ void onPreProcessResponse(ResponseHandlerInterface instance, HttpResponse response);
+
+ /**
+ * This method is called once by the system when the request has been fully
+ * sent, handled and finished. The library makes sure that a single response
+ * is post-processed only once.
+ *
+ * Please note: post-processing does NOT run on the main thread, and thus
+ * any UI activities that you must perform should be properly dispatched to
+ * the app's UI thread.
+ *
+ * @param instance An instance of this response object
+ * @param response The response to post-process
+ */
+ void onPostProcessResponse(ResponseHandlerInterface instance, HttpResponse response);
+
+ /**
+ * Will retrieve TAG Object if it's not already freed from memory
+ *
+ * @return Object TAG or null if it's been garbage collected
+ */
+ Object getTag();
+
+ /**
+ * Will set TAG to ResponseHandlerInterface implementation, which can be then obtained
+ * in implemented methods, such as onSuccess, onFailure, ...
+ *
+ * @param TAG Object to be set as TAG, will be placed in WeakReference
+ */
+ void setTag(Object TAG);
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RetryHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RetryHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6649464fa31ccb55d03bc556613a1c0812f7e25
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/RetryHandler.java
@@ -0,0 +1,122 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/*
+ Some of the retry logic in this class is heavily borrowed from the
+ fantastic droid-fu project: https://github.com/donnfelker/droid-fu
+*/
+
+package com.example.httplibrary.utils;
+
+
+import cz.msebera.android.httpclient.NoHttpResponseException;
+import cz.msebera.android.httpclient.client.HttpRequestRetryHandler;
+import cz.msebera.android.httpclient.client.methods.HttpUriRequest;
+import cz.msebera.android.httpclient.protocol.ExecutionContext;
+import cz.msebera.android.httpclient.protocol.HttpContext;
+import ohos.miscservices.timeutility.Time;
+
+import javax.net.ssl.SSLException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.HashSet;
+
+class RetryHandler implements HttpRequestRetryHandler {
+ private final static HashSet> exceptionWhitelist = new HashSet>();
+ private final static HashSet> exceptionBlacklist = new HashSet>();
+
+ static {
+ // Retry if the server dropped connection on us
+ exceptionWhitelist.add(NoHttpResponseException.class);
+ // retry-this, since it may happens as part of a Wi-Fi to 3G failover
+ exceptionWhitelist.add(UnknownHostException.class);
+ // retry-this, since it may happens as part of a Wi-Fi to 3G failover
+ exceptionWhitelist.add(SocketException.class);
+
+ // never retry timeouts
+ exceptionBlacklist.add(InterruptedIOException.class);
+ // never retry SSL handshake failures
+ exceptionBlacklist.add(SSLException.class);
+ }
+
+ private final int maxRetries;
+ private final int retrySleepTimeMS;
+
+ public RetryHandler(int maxRetries, int retrySleepTimeMS) {
+ this.maxRetries = maxRetries;
+ this.retrySleepTimeMS = retrySleepTimeMS;
+ }
+
+ static void addClassToWhitelist(Class> cls) {
+ exceptionWhitelist.add(cls);
+ }
+
+ static void addClassToBlacklist(Class> cls) {
+ exceptionBlacklist.add(cls);
+ }
+
+ @Override
+ public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
+ boolean retry = true;
+
+ Boolean b = (Boolean) context.getAttribute(ExecutionContext.HTTP_REQ_SENT);
+ boolean sent = (b != null && b);
+
+ if (executionCount > maxRetries) {
+ // Do not retry if over max retry count
+ retry = false;
+ } else if (isInList(exceptionWhitelist, exception)) {
+ // immediately retry if error is whitelisted
+ retry = true;
+ } else if (isInList(exceptionBlacklist, exception)) {
+ // immediately cancel retry if the error is blacklisted
+ retry = false;
+ } else if (!sent) {
+ // for most other errors, retry only if request hasn't been fully sent yet
+ retry = true;
+ }
+
+ if (retry) {
+ // resend all idempotent requests
+ HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
+ if (currentReq == null) {
+ return false;
+ }
+ }
+
+ if (retry) {
+ Time.sleep(retrySleepTimeMS);
+// SystemClock.sleep(retrySleepTimeMS);
+ } else {
+ exception.printStackTrace();
+ }
+
+ return retry;
+ }
+
+ protected boolean isInList(HashSet> list, Throwable error) {
+ for (Class> aList : list) {
+ if (aList.isInstance(error)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SerializableCookie.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SerializableCookie.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef2013f3bf816c61807af91ba1a4ba1aff48f837
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SerializableCookie.java
@@ -0,0 +1,74 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.cookie.Cookie;
+import cz.msebera.android.httpclient.impl.cookie.BasicClientCookie;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * A wrapper class around {@link Cookie} and/or {@link BasicClientCookie} designed for use in {@link
+ * PersistentCookieStore}.
+ */
+public class SerializableCookie implements Serializable {
+ private static final long serialVersionUID = 6374381828722046732L;
+
+ private transient final Cookie cookie;
+ private transient BasicClientCookie clientCookie;
+
+ public SerializableCookie(Cookie cookie) {
+ this.cookie = cookie;
+ }
+
+ public Cookie getCookie() {
+ Cookie bestCookie = cookie;
+ if (clientCookie != null) {
+ bestCookie = clientCookie;
+ }
+ return bestCookie;
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.writeObject(cookie.getName());
+ out.writeObject(cookie.getValue());
+ out.writeObject(cookie.getComment());
+ out.writeObject(cookie.getDomain());
+ out.writeObject(cookie.getExpiryDate());
+ out.writeObject(cookie.getPath());
+ out.writeInt(cookie.getVersion());
+ out.writeBoolean(cookie.isSecure());
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ String key = (String) in.readObject();
+ String value = (String) in.readObject();
+ clientCookie = new BasicClientCookie(key, value);
+ clientCookie.setComment((String) in.readObject());
+ clientCookie.setDomain((String) in.readObject());
+ clientCookie.setExpiryDate((Date) in.readObject());
+ clientCookie.setPath((String) in.readObject());
+ clientCookie.setVersion(in.readInt());
+ clientCookie.setSecure(in.readBoolean());
+ }
+}
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SimpleMultipartEntity.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SimpleMultipartEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..89e3481ff0df283ef5e7fa563ec4e4bad94cd6d6
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SimpleMultipartEntity.java
@@ -0,0 +1,291 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/*
+ This code is taken from Rafael Sanches' blog. Link is no longer working (as of 17th July 2015)
+ https://blog.rafaelsanches.com/2011/01/29/upload-using-multipart-post-using-httpclient-in-android/
+*/
+
+package com.example.httplibrary.utils;
+
+
+import cz.msebera.android.httpclient.Header;
+import cz.msebera.android.httpclient.HttpEntity;
+import cz.msebera.android.httpclient.message.BasicHeader;
+import cz.msebera.android.httpclient.protocol.HTTP;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Simplified multipart entity mainly used for sending one or more files.
+ */
+class SimpleMultipartEntity implements HttpEntity {
+
+ private static final String LOG_TAG = "SimpleMultipartEntity";
+
+ private static final String STR_CR_LF = "\r\n";
+ private static final byte[] CR_LF = STR_CR_LF.getBytes();
+ private static final byte[] TRANSFER_ENCODING_BINARY =
+ ("Content-Transfer-Encoding: binary" + STR_CR_LF).getBytes();
+
+ private final static char[] MULTIPART_CHARS =
+ "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+
+ private final String boundary;
+ private final byte[] boundaryLine;
+ private final byte[] boundaryEnd;
+ private final List fileParts = new ArrayList();
+ // The buffer we use for building the message excluding files and the last
+ // boundary
+ private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ private final ResponseHandlerInterface progressHandler;
+ private boolean isRepeatable;
+ private long bytesWritten;
+
+ private long totalSize;
+
+ public SimpleMultipartEntity(ResponseHandlerInterface progressHandler) {
+ final StringBuilder buf = new StringBuilder();
+ final Random rand = new Random();
+ for (int i = 0; i < 30; i++) {
+ buf.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
+ }
+
+ boundary = buf.toString();
+ boundaryLine = ("--" + boundary + STR_CR_LF).getBytes();
+ boundaryEnd = ("--" + boundary + "--" + STR_CR_LF).getBytes();
+
+ this.progressHandler = progressHandler;
+ }
+
+ public void addPart(String key, String value, String contentType) {
+ try {
+ out.write(boundaryLine);
+ out.write(createContentDisposition(key));
+ out.write(createContentType(contentType));
+ out.write(CR_LF);
+ out.write(value.getBytes());
+ out.write(CR_LF);
+ } catch (final IOException e) {
+ // Shall not happen on ByteArrayOutputStream
+ AsyncHttpClient.log.e(LOG_TAG, "addPart ByteArrayOutputStream exception", e);
+ }
+ }
+
+ public void addPartWithCharset(String key, String value, String charset) {
+ if (charset == null) charset = HTTP.UTF_8;
+ addPart(key, value, "text/plain; charset=" + charset);
+ }
+
+ public void addPart(String key, String value) {
+ addPartWithCharset(key, value, null);
+ }
+
+ public void addPart(String key, File file) {
+ addPart(key, file, null);
+ }
+
+ public void addPart(String key, File file, String type) {
+ fileParts.add(new FilePart(key, file, normalizeContentType(type)));
+ }
+
+ public void addPart(String key, File file, String type, String customFileName) {
+ fileParts.add(new FilePart(key, file, normalizeContentType(type), customFileName));
+ }
+
+ public void addPart(String key, String streamName, InputStream inputStream, String type)
+ throws IOException {
+
+ out.write(boundaryLine);
+
+ // Headers
+ out.write(createContentDisposition(key, streamName));
+ out.write(createContentType(type));
+ out.write(TRANSFER_ENCODING_BINARY);
+ out.write(CR_LF);
+
+ // Stream (file)
+ final byte[] tmp = new byte[4096];
+ int l;
+ while ((l = inputStream.read(tmp)) != -1) {
+ out.write(tmp, 0, l);
+ }
+
+ out.write(CR_LF);
+ out.flush();
+ }
+
+ private String normalizeContentType(String type) {
+ return type == null ? RequestParams.APPLICATION_OCTET_STREAM : type;
+ }
+
+ private byte[] createContentType(String type) {
+ String result = AsyncHttpClient.HEADER_CONTENT_TYPE + ": " + normalizeContentType(type) + STR_CR_LF;
+ return result.getBytes();
+ }
+
+ private byte[] createContentDisposition(String key) {
+ return (
+ AsyncHttpClient.HEADER_CONTENT_DISPOSITION +
+ ": form-data; name=\"" + key + "\"" + STR_CR_LF).getBytes();
+ }
+
+ private byte[] createContentDisposition(String key, String fileName) {
+ return (
+ AsyncHttpClient.HEADER_CONTENT_DISPOSITION +
+ ": form-data; name=\"" + key + "\"" +
+ "; filename=\"" + fileName + "\"" + STR_CR_LF).getBytes();
+ }
+
+ private void updateProgress(long count) {
+ bytesWritten += count;
+ progressHandler.sendProgressMessage(bytesWritten, totalSize);
+ }
+
+ @Override
+ public long getContentLength() {
+ long contentLen = out.size();
+ for (FilePart filePart : fileParts) {
+ long len = filePart.getTotalLength();
+ if (len < 0) {
+ return -1; // Should normally not happen
+ }
+ contentLen += len;
+ }
+ contentLen += boundaryEnd.length;
+ return contentLen;
+ }
+
+ // The following methods are from the HttpEntity interface
+
+ @Override
+ public Header getContentType() {
+ return new BasicHeader(
+ AsyncHttpClient.HEADER_CONTENT_TYPE,
+ "multipart/form-data; boundary=" + boundary);
+ }
+
+ @Override
+ public boolean isChunked() {
+ return false;
+ }
+
+ public void setIsRepeatable(boolean isRepeatable) {
+ this.isRepeatable = isRepeatable;
+ }
+
+ @Override
+ public boolean isRepeatable() {
+ return isRepeatable;
+ }
+
+ @Override
+ public boolean isStreaming() {
+ return false;
+ }
+
+ @Override
+ public void writeTo(final OutputStream outstream) throws IOException {
+ bytesWritten = 0;
+ totalSize = (int) getContentLength();
+ out.writeTo(outstream);
+ updateProgress(out.size());
+
+ for (FilePart filePart : fileParts) {
+ filePart.writeTo(outstream);
+ }
+ outstream.write(boundaryEnd);
+ updateProgress(boundaryEnd.length);
+ }
+
+ @Override
+ public Header getContentEncoding() {
+ return null;
+ }
+
+ @Override
+ public void consumeContent() throws IOException, UnsupportedOperationException {
+ if (isStreaming()) {
+ throw new UnsupportedOperationException(
+ "Streaming entity does not implement #consumeContent()");
+ }
+ }
+
+ @Override
+ public InputStream getContent() throws IOException, UnsupportedOperationException {
+ throw new UnsupportedOperationException(
+ "getContent() is not supported. Use writeTo() instead.");
+ }
+
+ private class FilePart {
+ public final File file;
+ public final byte[] header;
+
+ public FilePart(String key, File file, String type, String customFileName) {
+ header = createHeader(key, customFileName.isEmpty() ? file.getName() : customFileName, type);
+ this.file = file;
+ }
+
+ public FilePart(String key, File file, String type) {
+ header = createHeader(key, file.getName(), type);
+ this.file = file;
+ }
+
+ private byte[] createHeader(String key, String filename, String type) {
+ ByteArrayOutputStream headerStream = new ByteArrayOutputStream();
+ try {
+ headerStream.write(boundaryLine);
+
+ // Headers
+ headerStream.write(createContentDisposition(key, filename));
+ headerStream.write(createContentType(type));
+ headerStream.write(TRANSFER_ENCODING_BINARY);
+ headerStream.write(CR_LF);
+ } catch (IOException e) {
+ // Can't happen on ByteArrayOutputStream
+ AsyncHttpClient.log.e(LOG_TAG, "createHeader ByteArrayOutputStream exception", e);
+ }
+ return headerStream.toByteArray();
+ }
+
+ public long getTotalLength() {
+ long streamLength = file.length() + CR_LF.length;
+ return header.length + streamLength;
+ }
+
+ public void writeTo(OutputStream out) throws IOException {
+ out.write(header);
+ updateProgress(header.length);
+
+ FileInputStream inputStream = new FileInputStream(file);
+ final byte[] tmp = new byte[4096];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(tmp)) != -1) {
+ out.write(tmp, 0, bytesRead);
+ updateProgress(bytesRead);
+ }
+ out.write(CR_LF);
+ updateProgress(CR_LF.length);
+ out.flush();
+ AsyncHttpClient.silentCloseInputStream(inputStream);
+ }
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SyncHttpClient.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SyncHttpClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..115139cee6215b96eea2ee859a9936b9c7a8bc54
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/SyncHttpClient.java
@@ -0,0 +1,100 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+package com.example.httplibrary.utils;
+
+
+import cz.msebera.android.httpclient.client.methods.HttpUriRequest;
+import cz.msebera.android.httpclient.conn.scheme.SchemeRegistry;
+import cz.msebera.android.httpclient.impl.client.DefaultHttpClient;
+import cz.msebera.android.httpclient.protocol.HttpContext;
+import ohos.app.Context;
+
+/**
+ * Processes http requests in synchronous mode, so your caller thread will be blocked on each
+ * request
+ *
+ */
+public class SyncHttpClient extends AsyncHttpClient {
+
+ /**
+ * Creates a new SyncHttpClient with default constructor arguments values
+ */
+ public SyncHttpClient() {
+ super(false, 80, 443);
+ }
+
+ /**
+ * Creates a new SyncHttpClient.
+ *
+ * @param httpPort non-standard HTTP-only port
+ */
+ public SyncHttpClient(int httpPort) {
+ super(false, httpPort, 443);
+ }
+
+ /**
+ * Creates a new SyncHttpClient.
+ *
+ * @param httpPort non-standard HTTP-only port
+ * @param httpsPort non-standard HTTPS-only port
+ */
+ public SyncHttpClient(int httpPort, int httpsPort) {
+ super(false, httpPort, httpsPort);
+ }
+
+ /**
+ * Creates new SyncHttpClient using given params
+ *
+ * @param fixNoHttpResponseException Whether to fix or not issue, by ommiting SSL verification
+ * @param httpPort HTTP port to be used, must be greater than 0
+ * @param httpsPort HTTPS port to be used, must be greater than 0
+ */
+ public SyncHttpClient(boolean fixNoHttpResponseException, int httpPort, int httpsPort) {
+ super(fixNoHttpResponseException, httpPort, httpsPort);
+ }
+
+ /**
+ * Creates a new SyncHttpClient.
+ *
+ * @param schemeRegistry SchemeRegistry to be used
+ */
+ public SyncHttpClient(SchemeRegistry schemeRegistry) {
+ super(schemeRegistry);
+ }
+
+ @Override
+ protected RequestHandle sendRequest(DefaultHttpClient client,
+ HttpContext httpContext, HttpUriRequest uriRequest,
+ String contentType, ResponseHandlerInterface responseHandler,
+ Context context) {
+ if (contentType != null) {
+ uriRequest.addHeader(AsyncHttpClient.HEADER_CONTENT_TYPE, contentType);
+ }
+
+ responseHandler.setUseSynchronousMode(true);
+
+ /*
+ * will execute the request directly
+ */
+ newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context).run();
+
+ // Return a Request Handle that cannot be used to cancel the request
+ // because it is already complete by the time this returns
+ return new RequestHandle(null);
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/TextHttpResponseHandler.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/TextHttpResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2e1be73b01f1a0842765f3b9da3376227e2bcea
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/TextHttpResponseHandler.java
@@ -0,0 +1,125 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.Header;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Used to intercept and handle the responses from requests made using {@link AsyncHttpClient}. The
+ * {@link #onSuccess(int, Header[], String)} method is designed to be anonymously
+ * overridden with your own response handling code.
Additionally, you can override the
+ * {@link #onFailure(int, Header[], String, Throwable)}, {@link #onStart()}, and
+ * {@link #onFinish()} methods as required.
For example:
+ *
+ * AsyncHttpClient client = new AsyncHttpClient();
+ * client.get("https://www.google.com", new TextHttpResponseHandler() {
+ * @Override
+ * public void onStart() {
+ * // Initiated the request
+ * }
+ *
+ * @Override
+ * public void onSuccess(String responseBody) {
+ * // Successfully got a response
+ * }
+ *
+ * @Override
+ * public void onFailure(String responseBody, Throwable e) {
+ * // Response failed :(
+ * }
+ *
+ * @Override
+ * public void onFinish() {
+ * // Completed the request (either success or failure)
+ * }
+ * });
+ *
+ */
+public abstract class TextHttpResponseHandler extends AsyncHttpResponseHandler {
+
+ private static final String LOG_TAG = "TextHttpRH";
+
+ /**
+ * Creates new instance with default UTF-8 encoding
+ */
+ public TextHttpResponseHandler() {
+ this(DEFAULT_CHARSET);
+ }
+
+ /**
+ * Creates new instance with given string encoding
+ *
+ * @param encoding String encoding, see {@link #setCharset(String)}
+ */
+ public TextHttpResponseHandler(String encoding) {
+ super();
+ setCharset(encoding);
+ }
+
+ /**
+ * Attempts to encode response bytes as string of set encoding
+ *
+ * @param charset charset to create string with
+ * @param stringBytes response bytes
+ * @return String of set encoding or null
+ */
+ public static String getResponseString(byte[] stringBytes, String charset) {
+ try {
+ String toReturn = (stringBytes == null) ? null : new String(stringBytes, charset);
+ if (toReturn != null && toReturn.startsWith(UTF8_BOM)) {
+ return toReturn.substring(1);
+ }
+ return toReturn;
+ } catch (UnsupportedEncodingException e) {
+ AsyncHttpClient.log.e(LOG_TAG, "Encoding response into string failed", e);
+ return null;
+ }
+ }
+
+ /**
+ * Called when request fails
+ *
+ * @param statusCode http response status line
+ * @param headers response headers if any
+ * @param responseString string response of given charset
+ * @param throwable throwable returned when processing request
+ */
+ public abstract void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable);
+
+ /**
+ * Called when request succeeds
+ *
+ * @param statusCode http response status line
+ * @param headers response headers if any
+ * @param responseString string response of given charset
+ */
+ public abstract void onSuccess(int statusCode, Header[] headers, String responseString);
+
+ @Override
+ public void onSuccess(int statusCode, Header[] headers, byte[] responseBytes) {
+ onSuccess(statusCode, headers, getResponseString(responseBytes, getCharset()));
+ }
+
+ @Override
+ public void onFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
+ onFailure(statusCode, headers, getResponseString(responseBytes, getCharset()), throwable);
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/TokenCredentials.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/TokenCredentials.java
new file mode 100644
index 0000000000000000000000000000000000000000..07c88e364e5acf6b92519a142eed902cf993188b
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/TokenCredentials.java
@@ -0,0 +1,42 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+package com.example.httplibrary.utils;
+
+import cz.msebera.android.httpclient.auth.BasicUserPrincipal;
+import cz.msebera.android.httpclient.auth.Credentials;
+
+import java.security.Principal;
+
+public class TokenCredentials implements Credentials {
+ private Principal userPrincipal;
+
+ public TokenCredentials(String token) {
+ this.userPrincipal = new BasicUserPrincipal(token);
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return userPrincipal;
+ }
+
+ @Override
+ public String getPassword() {
+ return null;
+ }
+
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Utils.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Utils.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b9fa4f3a982012dde5d654616d3e869277a54eb
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/Utils.java
@@ -0,0 +1,56 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
+
+/**
+ * Provides general assert utils, which are stripped by Android SDK on
+ * compile/runtime, to work on release builds
+ */
+class Utils {
+
+ private Utils() {
+ }
+
+ /**
+ * Will throw AssertionError, if expression is not true
+ *
+ * @param expression result of your asserted condition
+ * @param failedMessage message to be included in error log
+ * @throws AssertionError
+ */
+ public static void asserts(final boolean expression, final String failedMessage) {
+ if (!expression) {
+ throw new AssertionError(failedMessage);
+ }
+ }
+
+ /**
+ * Will throw IllegalArgumentException if provided object is null on runtime
+ *
+ * @param argument object that should be asserted as not null
+ * @param name name of the object asserted
+ * @throws IllegalArgumentException
+ */
+ public static T notNull(final T argument, final String name) {
+ if (argument == null) {
+ throw new IllegalArgumentException(name + " should not be null!");
+ }
+ return argument;
+ }
+}
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/package-info.java b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b8166c26b7e14dee208465410f13c507e26852b
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/java/com/example/httplibrary/utils/package-info.java
@@ -0,0 +1,19 @@
+/*
+ Android Asynchronous Http Client
+ Copyright (c) 2011 James Smith
+ https://github.com/android-async-http/android-async-http
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package com.example.httplibrary.utils;
\ No newline at end of file
diff --git a/001.Http_OpenHarmony-master/code/httplibrary/src/main/resources/base/element/string.json b/001.Http_OpenHarmony-master/code/httplibrary/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..8aa48534037b5902315b7dd8e76a3d9c419dbe91
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/httplibrary/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "HttpLibrary"
+ }
+ ]
+}
diff --git a/001.Http_OpenHarmony-master/code/settings.gradle b/001.Http_OpenHarmony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..6e0ed4f335108197250ce8162aa0b17c51104cca
--- /dev/null
+++ b/001.Http_OpenHarmony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':httplibrary'
diff --git "a/001.Http_OpenHarmony-master/doc/001.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204AsyncHttpt\347\275\221\347\273\234\350\257\267\346\261\202\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/001.Http_OpenHarmony-master/doc/001.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204AsyncHttpt\347\275\221\347\273\234\350\257\267\346\261\202\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..9ed0e297b99f3283a77157135747bd0dce90096a
Binary files /dev/null and "b/001.Http_OpenHarmony-master/doc/001.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204AsyncHttpt\347\275\221\347\273\234\350\257\267\346\261\202\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/002.Logger_OpenHarmony-master/code/.gitignore b/002.Logger_OpenHarmony-master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/002.Logger_OpenHarmony-master/code/.idea/.gitignore b/002.Logger_OpenHarmony-master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/002.Logger_OpenHarmony-master/code/.idea/compiler.xml b/002.Logger_OpenHarmony-master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/.idea/gradle.xml b/002.Logger_OpenHarmony-master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2d076d2f02152eacadf306e0af929d2c18ea97f
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/.idea/jarRepositories.xml b/002.Logger_OpenHarmony-master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/.idea/misc.xml b/002.Logger_OpenHarmony-master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_106113203.json b/002.Logger_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_106113203.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_106113203.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/.idea/previewer/previewConfig.json b/002.Logger_OpenHarmony-master/code/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..aa81fdc628c6b30a045626455caf76cfe2c52d1c
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/previewer/previewConfig.json
@@ -0,0 +1,9 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "E:\\MyApplication\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/.idea/vcs.xml b/002.Logger_OpenHarmony-master/code/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/.gitignore b/002.Logger_OpenHarmony-master/code/Logger_harmony/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/build.gradle b/002.Logger_OpenHarmony-master/code/Logger_harmony/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..972645f6b0acde106dafede80a9c0852f6f7df0d
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+ implementation 'org.jetbrains:annotations:15.0'
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/config.json b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..47fbf57e303cd4ae130f29c4823b87af0a7a4821
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/config.json
@@ -0,0 +1,28 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {
+ },
+ "module": {
+ "package": "com.example.logger_harmony",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "Logger_harmony",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/CsvFormatStrategy.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/CsvFormatStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..31e87a3d49d0bf720783b879b03e69b46ef46024
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/CsvFormatStrategy.java
@@ -0,0 +1,153 @@
+package com.example.logger_harmony;
+
+
+import ohos.app.Context;
+import ohos.app.Environment;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+
+/**
+ * CSV formatted file logging for Android.
+ * Writes to CSV the following data:
+ * epoch timestamp, ISO8601 timestamp (human-readable), log level, tag, log message.
+ */
+public class CsvFormatStrategy implements FormatStrategy {
+
+ private static final String NEW_LINE = System.getProperty("line.separator");
+ private static final String NEW_LINE_REPLACEMENT = " ";
+ private static final String SEPARATOR = ",";
+
+ private final Date date;
+ private final SimpleDateFormat dateFormat;
+ private final LogStrategy logStrategy;
+ @Nullable
+ private final String tag;
+
+ private CsvFormatStrategy(Builder builder) {
+ checkNotNull(builder);
+
+ date = builder.date;
+ dateFormat = builder.dateFormat;
+ logStrategy = builder.logStrategy;
+ tag = builder.tag;
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ @Override
+ public void log(int priority, @Nullable String onceOnlyTag, String message) {
+ checkNotNull(message);
+
+ String tag = formatTag(onceOnlyTag);
+
+ date.setTime(System.currentTimeMillis());
+
+ StringBuilder builder = new StringBuilder();
+
+ // machine-readable date/time
+ builder.append(Long.toString(date.getTime()));
+
+ // human-readable date/time
+ builder.append(SEPARATOR);
+ builder.append(dateFormat.format(date));
+
+ // level
+ builder.append(SEPARATOR);
+ builder.append(Utils.logLevel(priority));
+
+ // tag
+ builder.append(SEPARATOR);
+ builder.append(tag);
+
+ // message
+ if (message.contains(NEW_LINE)) {
+ // a new line would break the CSV format, so we replace it here
+ message = message.replaceAll(NEW_LINE, NEW_LINE_REPLACEMENT);
+ }
+ builder.append(SEPARATOR);
+ builder.append(message);
+
+ // new line
+ builder.append(NEW_LINE);
+
+ logStrategy.log(priority, tag, builder.toString());
+ }
+
+ @Nullable
+ private String formatTag(@Nullable String tag) {
+ if (!Utils.isEmpty(tag) && !Utils.equals(this.tag, tag)) {
+ return this.tag + "-" + tag;
+ }
+ return this.tag;
+ }
+
+ public static final class Builder {
+ private static final int MAX_BYTES = 500 * 1024; // 500K averages to a 4000 lines per file
+
+ Date date;
+ SimpleDateFormat dateFormat;
+ LogStrategy logStrategy;
+ String tag = "PRETTY_LOGGER";
+
+ private Builder() {
+ }
+
+ public Builder date(@Nullable Date val) {
+ date = val;
+ return this;
+ }
+
+ public Builder dateFormat(@Nullable SimpleDateFormat val) {
+ dateFormat = val;
+ return this;
+ }
+
+ public Builder logStrategy(@Nullable LogStrategy val) {
+ logStrategy = val;
+ return this;
+ }
+
+ public Builder tag(@Nullable String tag) {
+ this.tag = tag;
+ return this;
+ }
+
+ public CsvFormatStrategy build(Context context) {
+ if (date == null) {
+ date = new Date();
+ }
+ if (dateFormat == null) {
+ dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS", Locale.UK);
+ }
+ if (logStrategy == null) {
+// String diskPath = Environment.DIRECTORY_DOCUMENTS;
+// String folder = diskPath + File.separatorChar + "logger";
+
+//
+//// HandlerThread ht = new HandlerThread("AndroidFileLogger." + folder);
+//// ht.start();
+//// Handler handler = new DiskLogStrategy.WriteHandler(ht.getLooper(), folder, MAX_BYTES);
+//
+ File distDir = context.getDistributedDir();
+ String filePath = distDir + File.separator + "logger.csv";
+
+ EventRunner eventRunner = EventRunner.create(true);
+ EventHandler eventHandler = new DiskLogStrategy.WriteHandler(eventRunner, filePath);
+ logStrategy = new DiskLogStrategy(eventHandler);
+
+ }
+ return new CsvFormatStrategy(this);
+ }
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/DiskLogAdapter.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/DiskLogAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..28985ff04542b89d06014e222f788624bd2f1988
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/DiskLogAdapter.java
@@ -0,0 +1,34 @@
+package com.example.logger_harmony;
+
+
+import ohos.app.Context;
+import org.jetbrains.annotations.Nullable;
+
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+/**
+ * This is used to saves log messages to the disk.
+ * By default it uses {@link CsvFormatStrategy} to translates text message into CSV format.
+ */
+public class DiskLogAdapter implements LogAdapter {
+
+ private final FormatStrategy formatStrategy;
+
+ public DiskLogAdapter(Context context) {
+ formatStrategy = CsvFormatStrategy.newBuilder().build(context);
+ }
+
+ public DiskLogAdapter( FormatStrategy formatStrategy) {
+ this.formatStrategy = checkNotNull(formatStrategy);
+ }
+
+ @Override
+ public boolean isLoggable(int priority, @Nullable String tag) {
+ return true;
+ }
+
+ @Override
+ public void log(int priority, @Nullable String tag, String message) {
+ formatStrategy.log(priority, tag, message);
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/DiskLogStrategy.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/DiskLogStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d2912e6b02def31999e276815464630449dfeb8
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/DiskLogStrategy.java
@@ -0,0 +1,62 @@
+package com.example.logger_harmony;
+
+
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.eventhandler.InnerEvent;
+import ohos.hiviewdfx.HiLog;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+/**
+ * Abstract class that takes care of background threading the file log operation on Android.
+ * implementing classes are free to directly perform I/O operations there.
+ *
+ * Writes all logs to the disk with CSV format.
+ */
+public class DiskLogStrategy implements LogStrategy {
+
+ private final EventHandler handler;
+
+ public DiskLogStrategy(EventHandler handler) {
+ this.handler = checkNotNull(handler);
+ }
+
+ @Override
+ public void log(int level, @Nullable String tag, String message) {
+ checkNotNull(message);
+
+ InnerEvent event = InnerEvent.get(0, message);
+ handler.sendEvent(event);
+ }
+
+ static class WriteHandler extends EventHandler {
+
+ private String folder;
+
+ public WriteHandler(EventRunner runner, String filePath) throws IllegalArgumentException {
+ super(runner);
+ this.folder = filePath;
+ }
+
+ @Override
+ protected void processEvent(InnerEvent event) {
+ super.processEvent(event);
+ try {
+ String param = event.object.toString();
+ FileWriter fileWriter = new FileWriter(folder, true);
+ fileWriter.write(param);
+ fileWriter.flush();
+ fileWriter.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/FormatStrategy.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/FormatStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ee837896017593b9a97eeac713cf1958baef6bc
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/FormatStrategy.java
@@ -0,0 +1,14 @@
+package com.example.logger_harmony;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Used to determine how messages should be printed or saved.
+ *
+ * @see PrettyFormatStrategy
+ * @see CsvFormatStrategy
+ */
+public interface FormatStrategy {
+
+ void log(int priority, @Nullable String tag, String message);
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/HarmonyOsLogAdapter.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/HarmonyOsLogAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..a30a323724e01622e2b2f0ab949d68ea5c778b27
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/HarmonyOsLogAdapter.java
@@ -0,0 +1,43 @@
+package com.example.logger_harmony;
+
+
+import org.jetbrains.annotations.Nullable;
+
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+/**
+ * Android terminal log output implementation for {@link LogAdapter}.
+ *
+ * Prints output to LogCat with pretty borders.
+ *
+ *
+ * ┌──────────────────────────
+ * │ Method stack history
+ * ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ * │ Log message
+ * └──────────────────────────
+ *
+ */
+public class HarmonyOsLogAdapter implements LogAdapter {
+
+ private final FormatStrategy formatStrategy;
+
+ public HarmonyOsLogAdapter() {
+ this.formatStrategy = PrettyFormatStrategy.newBuilder().build();
+ }
+
+ public HarmonyOsLogAdapter(FormatStrategy formatStrategy) {
+ this.formatStrategy = checkNotNull(formatStrategy);
+ }
+
+ @Override
+ public boolean isLoggable(int priority, @Nullable String tag) {
+ return true;
+ }
+
+ @Override
+ public void log(int priority, @Nullable String tag, String message) {
+ formatStrategy.log(priority, tag, message);
+ }
+
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogAdapter.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba8cd7f21039ed6a4037617e2d2e285cd6576a0c
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogAdapter.java
@@ -0,0 +1,31 @@
+package com.example.logger_harmony;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Provides a common interface to emits logs through. This is a required contract for Logger.
+ *
+ * @see HarmonyOsLogAdapter
+ * @see DiskLogAdapter
+ */
+public interface LogAdapter {
+
+ /**
+ * Used to determine whether log should be printed out or not.
+ *
+ * @param priority is the log level e.g. DEBUG, WARNING
+ * @param tag is the given tag for the log message
+ * @return is used to determine if log should printed.
+ * If it is true, it will be printed, otherwise it'll be ignored.
+ */
+ boolean isLoggable(int priority, @Nullable String tag);
+
+ /**
+ * Each log will use this pipeline
+ *
+ * @param priority is the log level e.g. DEBUG, WARNING
+ * @param tag is the given tag for the log message.
+ * @param message is the given message for the log message.
+ */
+ void log(int priority, @Nullable String tag, String message);
+}
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogStrategy.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8af639d7fe1ca3829c235241cee1948a0b3d389
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogStrategy.java
@@ -0,0 +1,22 @@
+package com.example.logger_harmony;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Determines destination target for the logs such as Disk, Logcat etc.
+ *
+ * @see LogcatLogStrategy
+ * @see DiskLogStrategy
+ */
+public interface LogStrategy {
+
+ /**
+ * This is invoked by Logger each time a log message is processed.
+ * Interpret this method as last destination of the log in whole pipeline.
+ *
+ * @param priority is the log level e.g. DEBUG, WARNING
+ * @param tag is the given tag for the log message.
+ * @param message is the given message for the log message.
+ */
+ void log(int priority, @Nullable String tag, String message);
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogcatLogStrategy.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogcatLogStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..88266823a0afaebc0c12eeb10e7e0e179952dfde
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LogcatLogStrategy.java
@@ -0,0 +1,54 @@
+package com.example.logger_harmony;
+
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import org.jetbrains.annotations.Nullable;
+
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+/**
+ * LogCat implementation for {@link LogStrategy}
+ *
+ * This simply prints out all logs to Logcat by using standard {@link} class.
+ */
+public class LogcatLogStrategy implements LogStrategy {
+
+ static final String DEFAULT_TAG = "NO_TAG";
+
+
+ @Override
+ public void log(int priority, @Nullable String tag, String message) {
+ checkNotNull(message);
+
+ if (tag == null) {
+ tag = DEFAULT_TAG;
+ }
+ HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00201, tag);
+
+// public static final int DEBUG = 3;
+// public static final int INFO = 4;
+// public static final int WARN = 5;
+// public static final int ERROR = 6;
+// public static final int ASSERT = 7;
+
+
+ switch (priority) {
+ case Logger.DEBUG:
+ HiLog.debug(label, message);
+ break;
+ case Logger.INFO:
+ HiLog.info(label, message);
+ break;
+ case Logger.WARN:
+ HiLog.warn(label, message);
+ break;
+ case Logger.ERROR:
+ HiLog.error(label, message);
+ break;
+ case Logger.ASSERT:
+ HiLog.fatal(label, message);
+ break;
+
+ }
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Logger.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Logger.java
new file mode 100644
index 0000000000000000000000000000000000000000..8856ff2e2bae8a4cbdb79dea69742f0db8f120a8
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Logger.java
@@ -0,0 +1,163 @@
+package com.example.logger_harmony;
+
+
+import org.jetbrains.annotations.Nullable;
+
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+/**
+ *
+ * ┌────────────────────────────────────────────
+ * │ LOGGER
+ * ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ * │ Standard logging mechanism
+ * ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ * │ But more pretty, simple and powerful
+ * └────────────────────────────────────────────
+ *
+ *
+ * How to use it
+ * Initialize it first
+ *
+ * Logger.addLogAdapter(new AndroidLogAdapter());
+ *
+ *
+ * And use the appropriate static Logger methods.
+ *
+ *
+ * Logger.d("debug");
+ * Logger.e("error");
+ * Logger.w("warning");
+ * Logger.v("verbose");
+ * Logger.i("information");
+ * Logger.wtf("What a Terrible Failure");
+ *
+ *
+ * String format arguments are supported
+ *
+ * Logger.d("hello %s", "world");
+ *
+ *
+ * Collections are support ed(only available for debug logs)
+ *
+ * Logger.d(MAP);
+ * Logger.d(SET);
+ * Logger.d(LIST);
+ * Logger.d(ARRAY);
+ *
+ *
+ * Json and Xml support (output will be in debug level)
+ *
+ * Logger.json(JSON_CONTENT);
+ * Logger.xml(XML_CONTENT);
+ *
+ *
+ * Customize Logger
+ * Based on your needs, you can change the following settings:
+ *
+ * Different {@link LogAdapter}
+ * Different {@link FormatStrategy}
+ * Different {@link LogStrategy}
+ *
+ *
+ * @see LogAdapter
+ * @see FormatStrategy
+ * @see LogStrategy
+ */
+public final class Logger {
+
+ public static final int VERBOSE = 2;
+ public static final int DEBUG = 3;
+ public static final int INFO = 4;
+ public static final int WARN = 5;
+ public static final int ERROR = 6;
+ public static final int ASSERT = 7;
+
+ private static Printer printer = new LoggerPrinter();
+
+ private Logger() {
+ //no instance
+ }
+
+ public static void printer( Printer printer) {
+ Logger.printer = checkNotNull(printer);
+ }
+
+ public static void addLogAdapter( LogAdapter adapter) {
+ printer.addAdapter(checkNotNull(adapter));
+ }
+
+ public static void clearLogAdapters() {
+ printer.clearLogAdapters();
+ }
+
+ /**
+ * Given tag will be used as tag only once for this method call regardless of the tag that's been
+ * set during initialization. After this invocation, the general tag that's been set will
+ * be used for the subsequent log calls
+ */
+ public static Printer t(@Nullable String tag) {
+ return printer.t(tag);
+ }
+
+ /**
+ * General log function that accepts all configurations as parameter
+ */
+ public static void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable throwable) {
+ printer.log(priority, tag, message, throwable);
+ }
+
+ public static void d(String message, @Nullable Object... args) {
+ printer.d(message, args);
+ }
+
+ public static void d(@Nullable Object object) {
+ printer.d(object);
+ }
+
+ public static void e(String message, @Nullable Object... args) {
+ printer.e(null, message, args);
+ }
+
+ public static void e(@Nullable Throwable throwable, String message, @Nullable Object... args) {
+ printer.e(throwable, message, args);
+ }
+
+ public static void i(String message, @Nullable Object... args) {
+ printer.i(message, args);
+ }
+ public static void i(@Nullable Object object) {
+ printer.i(object);
+ }
+
+ public static void v(String message, @Nullable Object... args) {
+ printer.v(message, args);
+ }
+
+ public static void w(String message, @Nullable Object... args) {
+ printer.w(message, args);
+ }
+
+ /**
+ * Tip: Use this for exceptional situations to log
+ * ie: Unexpected errors etc
+ */
+ public static void wtf(String message, @Nullable Object... args) {
+ printer.wtf(message, args);
+ }
+
+ /**
+ * Formats the given json content and print it
+ */
+ public static void json(@Nullable String json) {
+ printer.json(json);
+ }
+
+ /**
+ * Formats the given xml content and print it
+ */
+ public static void xml(@Nullable String xml) {
+ printer.xml(xml);
+ }
+
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LoggerPrinter.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LoggerPrinter.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f4b3f33afc6bdb297a20c2703d2e449efe8bedd
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/LoggerPrinter.java
@@ -0,0 +1,191 @@
+package com.example.logger_harmony;
+
+
+import org.jetbrains.annotations.Nullable;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.example.logger_harmony.Logger.*;
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+class LoggerPrinter implements Printer {
+
+ /**
+ * It is used for json pretty print
+ */
+ private static final int JSON_INDENT = 2;
+
+ /**
+ * Provides one-time used tag for the log message
+ */
+ private final ThreadLocal localTag = new ThreadLocal<>();
+
+ private final List logAdapters = new ArrayList<>();
+
+ @Override
+ public Printer t(String tag) {
+ if (tag != null) {
+ localTag.set(tag);
+ }
+ return this;
+ }
+
+ @Override
+ public void d(String message, @Nullable Object... args) {
+ log(DEBUG, null, message, args);
+ }
+
+ @Override
+ public void d(@Nullable Object object) {
+ log(DEBUG, null, Utils.toString(object));
+ }
+
+ @Override
+ public void e(String message, @Nullable Object... args) {
+ e(null, message, args);
+ }
+
+ @Override
+ public void e(@Nullable Throwable throwable, String message, @Nullable Object... args) {
+ log(ERROR, throwable, message, args);
+ }
+
+ @Override
+ public void w(String message, @Nullable Object... args) {
+ log(WARN, null, message, args);
+ }
+
+ @Override
+ public void i(String message, @Nullable Object... args) {
+ log(INFO, null, message, args);
+ }
+
+ @Override
+ public void i(@Nullable Object object) {
+ log(INFO, null, Utils.toString(object));
+
+ }
+
+ @Override
+ public void v(String message, @Nullable Object... args) {
+ log(VERBOSE, null, message, args);
+ }
+
+ @Override
+ public void wtf(String message, @Nullable Object... args) {
+ log(ASSERT, null, message, args);
+ }
+
+ @Override
+ public void json(@Nullable String json) {
+ if (Utils.isEmpty(json)) {
+ d("Empty/Null json content");
+ return;
+ }
+ try {
+ json = json.trim();
+ if (json.startsWith("{")) {
+ JSONObject jsonObject = new JSONObject(json);
+ String message = jsonObject.toString(JSON_INDENT);
+ i(message);
+ return;
+ }
+ if (json.startsWith("[")) {
+ JSONArray jsonArray = new JSONArray(json);
+ String message = jsonArray.toString(JSON_INDENT);
+ i(message);
+ return;
+ }
+ e("Invalid Json");
+ } catch (Exception e) {
+ e("Invalid Json");
+ }
+ }
+
+ @Override
+ public void xml(@Nullable String xml) {
+ if (Utils.isEmpty(xml)) {
+ d("Empty/Null xml content");
+ return;
+ }
+// try {
+//
+// Source xmlInput = new StreamSource(new StringReader(xml));
+// StreamResult xmlOutput = new StreamResult(new StringWriter());
+//
+// Transformer transformer = TransformerFactory.newInstance().newTransformer();
+// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+// transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+// transformer.transform(xmlInput, xmlOutput);
+// d(xmlOutput.getWriter().toString().replaceFirst(">", ">\n"));
+// } catch (TransformerException e) {
+// e("Invalid xml");
+// }
+ }
+
+ @Override
+ public synchronized void log(int priority,
+ @Nullable String tag,
+ @Nullable String message,
+ @Nullable Throwable throwable) {
+ if (throwable != null && message != null) {
+ message += " : " + Utils.getStackTraceString(throwable);
+ }
+ if (throwable != null && message == null) {
+ message = Utils.getStackTraceString(throwable);
+ }
+ if (Utils.isEmpty(message)) {
+ message = "Empty/NULL log message";
+ }
+
+ for (LogAdapter adapter : logAdapters) {
+ if (adapter.isLoggable(priority, tag)) {
+ adapter.log(priority, tag, message);
+ }
+ }
+ }
+
+ @Override
+ public void clearLogAdapters() {
+ logAdapters.clear();
+ }
+
+ @Override
+ public void addAdapter(LogAdapter adapter) {
+ logAdapters.add(checkNotNull(adapter));
+ }
+
+ /**
+ * This method is synchronized in order to avoid messy of logs' order.
+ */
+ private synchronized void log(int priority,
+ @Nullable Throwable throwable,
+ String msg,
+ @Nullable Object... args) {
+ checkNotNull(msg);
+
+ String tag = getTag();
+ String message = createMessage(msg, args);
+ log(priority, tag, message, throwable);
+ }
+
+ /**
+ * @return the appropriate tag based on local or global
+ */
+ @Nullable
+ private String getTag() {
+ String tag = localTag.get();
+ if (tag != null) {
+ localTag.remove();
+ return tag;
+ }
+ return null;
+ }
+
+ private String createMessage(String message, @Nullable Object... args) {
+ return args == null || args.length == 0 ? message : String.format(message, args);
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/PrettyFormatStrategy.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/PrettyFormatStrategy.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d952f7a3cde7d1b884fd6181de2ab86bdd711b0
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/PrettyFormatStrategy.java
@@ -0,0 +1,258 @@
+package com.example.logger_harmony;
+
+import org.jetbrains.annotations.Nullable;
+
+import static com.example.logger_harmony.Utils.checkNotNull;
+
+/**
+ * Draws borders around the given log message along with additional information such as :
+ *
+ *
+ * Thread information
+ * Method stack trace
+ *
+ *
+ *
+ * ┌──────────────────────────
+ * │ Method stack history
+ * ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ * │ Thread information
+ * ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ * │ Log message
+ * └──────────────────────────
+ *
+ *
+ * Customize
+ *
+ * FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
+ * .showThreadInfo(false) // (Optional) Whether to show thread info or not. Default true
+ * .methodCount(0) // (Optional) How many method line to show. Default 2
+ * .methodOffset(7) // (Optional) Hides internal method calls up to offset. Default 5
+ * .logStrategy(customLog) // (Optional) Changes the log strategy to print out. Default LogCat
+ * .tag("My custom tag") // (Optional) Global tag for every log. Default PRETTY_LOGGER
+ * .build();
+ *
+ */
+public class PrettyFormatStrategy implements FormatStrategy {
+
+ /**
+ * Android's max limit for a log entry is ~4076 bytes,
+ * so 4000 bytes is used as chunk size since default charset
+ * is UTF-8
+ */
+ private static final int CHUNK_SIZE = 4000;
+
+ /**
+ * The minimum stack trace index, starts at this class after two native calls.
+ */
+ private static final int MIN_STACK_OFFSET = 5;
+
+ /**
+ * Drawing toolbox
+ */
+ private static final char TOP_LEFT_CORNER = '┌';
+ private static final char BOTTOM_LEFT_CORNER = '└';
+ private static final char MIDDLE_CORNER = '├';
+ private static final char HORIZONTAL_LINE = '│';
+ private static final String DOUBLE_DIVIDER = "────────────────────────────────────────────────────────";
+ private static final String SINGLE_DIVIDER = "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄";
+ private static final String TOP_BORDER = TOP_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER;
+ private static final String BOTTOM_BORDER = BOTTOM_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER;
+ private static final String MIDDLE_BORDER = MIDDLE_CORNER + SINGLE_DIVIDER + SINGLE_DIVIDER;
+
+ private final int methodCount;
+ private final int methodOffset;
+ private final boolean showThreadInfo;
+ private final LogStrategy logStrategy;
+ @Nullable
+ private final String tag;
+
+ private PrettyFormatStrategy( Builder builder) {
+ checkNotNull(builder);
+
+ methodCount = builder.methodCount;
+ methodOffset = builder.methodOffset;
+ showThreadInfo = builder.showThreadInfo;
+ logStrategy = builder.logStrategy;
+ tag = builder.tag;
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ @Override
+ public void log(int priority, @Nullable String onceOnlyTag, String message) {
+ checkNotNull(message);
+
+ String tag = formatTag(onceOnlyTag);
+
+ logTopBorder(priority, tag);
+ logHeaderContent(priority, tag, methodCount);
+
+ //get bytes of message with system's default charset (which is UTF-8 for Android)
+ byte[] bytes = message.getBytes();
+ int length = bytes.length;
+ if (length <= CHUNK_SIZE) {
+ if (methodCount > 0) {
+ logDivider(priority, tag);
+ }
+ logContent(priority, tag, message);
+ logBottomBorder(priority, tag);
+ return;
+ }
+ if (methodCount > 0) {
+ logDivider(priority, tag);
+ }
+ for (int i = 0; i < length; i += CHUNK_SIZE) {
+ int count = Math.min(length - i, CHUNK_SIZE);
+ //create a new String with system's default charset (which is UTF-8 for Android)
+ logContent(priority, tag, new String(bytes, i, count));
+ }
+ logBottomBorder(priority, tag);
+ }
+
+ private void logTopBorder(int logType, @Nullable String tag) {
+ logChunk(logType, tag, TOP_BORDER);
+ }
+
+ @SuppressWarnings("StringBufferReplaceableByString")
+ private void logHeaderContent(int logType, @Nullable String tag, int methodCount) {
+ StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+ if (showThreadInfo) {
+ logChunk(logType, tag, HORIZONTAL_LINE + " Thread: " + Thread.currentThread().getName());
+ logDivider(logType, tag);
+ }
+ String level = "";
+
+ int stackOffset = getStackOffset(trace) + methodOffset;
+
+ //corresponding method count with the current stack may exceeds the stack trace. Trims the count
+ if (methodCount + stackOffset > trace.length) {
+ methodCount = trace.length - stackOffset - 1;
+ }
+
+ for (int i = methodCount; i > 0; i--) {
+ int stackIndex = i + stackOffset;
+ if (stackIndex >= trace.length) {
+ continue;
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append(HORIZONTAL_LINE)
+ .append(' ')
+ .append(level)
+ .append(getSimpleClassName(trace[stackIndex].getClassName()))
+ .append(".")
+ .append(trace[stackIndex].getMethodName())
+ .append(" ")
+ .append(" (")
+ .append(trace[stackIndex].getFileName())
+ .append(":")
+ .append(trace[stackIndex].getLineNumber())
+ .append(")");
+ level += " ";
+ logChunk(logType, tag, builder.toString());
+ }
+ }
+
+ private void logBottomBorder(int logType, @Nullable String tag) {
+ logChunk(logType, tag, BOTTOM_BORDER);
+ }
+
+ private void logDivider(int logType, @Nullable String tag) {
+ logChunk(logType, tag, MIDDLE_BORDER);
+ }
+
+ private void logContent(int logType, @Nullable String tag, String chunk) {
+ checkNotNull(chunk);
+
+ String[] lines = chunk.split(System.getProperty("line.separator"));
+ for (String line : lines) {
+ logChunk(logType, tag, HORIZONTAL_LINE + " " + line);
+ }
+ }
+
+ private void logChunk(int priority, @Nullable String tag, String chunk) {
+ checkNotNull(chunk);
+
+ logStrategy.log(priority, tag, chunk);
+ }
+
+ private String getSimpleClassName(String name) {
+ checkNotNull(name);
+
+ int lastIndex = name.lastIndexOf(".");
+ return name.substring(lastIndex + 1);
+ }
+
+ /**
+ * Determines the starting index of the stack trace, after method calls made by this class.
+ *
+ * @param trace the stack trace
+ * @return the stack offset
+ */
+ private int getStackOffset( StackTraceElement[] trace) {
+ checkNotNull(trace);
+
+ for (int i = MIN_STACK_OFFSET; i < trace.length; i++) {
+ StackTraceElement e = trace[i];
+ String name = e.getClassName();
+ if (!name.equals(LoggerPrinter.class.getName()) && !name.equals(Logger.class.getName())) {
+ return --i;
+ }
+ }
+ return -1;
+ }
+
+ @Nullable private String formatTag(@Nullable String tag) {
+ if (!Utils.isEmpty(tag) && !Utils.equals(this.tag, tag)) {
+ return this.tag + "-" + tag;
+ }
+ return this.tag;
+ }
+
+ public static class Builder {
+ int methodCount = 2;
+ int methodOffset = 0;
+ boolean showThreadInfo = true;
+ @Nullable LogStrategy logStrategy;
+ @Nullable
+ String tag = "PRETTY_LOGGER";
+
+ private Builder() {
+ }
+
+ public Builder methodCount(int val) {
+ methodCount = val;
+ return this;
+ }
+
+ public Builder methodOffset(int val) {
+ methodOffset = val;
+ return this;
+ }
+
+ public Builder showThreadInfo(boolean val) {
+ showThreadInfo = val;
+ return this;
+ }
+
+ public Builder logStrategy(@Nullable LogStrategy val) {
+ logStrategy = val;
+ return this;
+ }
+
+ public Builder tag(@Nullable String tag) {
+ this.tag = tag;
+ return this;
+ }
+
+ public PrettyFormatStrategy build() {
+ if (logStrategy == null) {
+ logStrategy = new LogcatLogStrategy();
+ }
+ return new PrettyFormatStrategy(this);
+ }
+ }
+
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Printer.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Printer.java
new file mode 100644
index 0000000000000000000000000000000000000000..c316200cfd30a35bf0940119f611132bc610790b
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Printer.java
@@ -0,0 +1,46 @@
+package com.example.logger_harmony;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A proxy interface to enable additional operations.
+ * Contains all possible Log message usages.
+ */
+public interface Printer {
+
+ void addAdapter(LogAdapter adapter);
+
+ Printer t(@Nullable String tag);
+
+ void d(String message, @Nullable Object... args);
+
+ void d(@Nullable Object object);
+
+ void e(String message, @Nullable Object... args);
+
+ void e(@Nullable Throwable throwable, String message, @Nullable Object... args);
+
+ void w(String message, @Nullable Object... args);
+
+ void i(String message, @Nullable Object... args);
+
+ void i(@Nullable Object object);
+
+ void v(String message, @Nullable Object... args);
+
+ void wtf(String message, @Nullable Object... args);
+
+ /**
+ * Formats the given json content and print it
+ */
+ void json(@Nullable String json);
+
+ /**
+ * Formats the given xml content and print it
+ */
+ void xml(@Nullable String xml);
+
+ void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable throwable);
+
+ void clearLogAdapters();
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Utils.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Utils.java
new file mode 100644
index 0000000000000000000000000000000000000000..215c20b49b78a5564dfe3191905abf96ed8b65de
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/com/example/logger_harmony/Utils.java
@@ -0,0 +1,151 @@
+package com.example.logger_harmony;
+
+import org.jetbrains.annotations.Nullable;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+import static com.example.logger_harmony.Logger.*;
+
+/**
+ * Provides convenient methods to some common operations
+ */
+final class Utils {
+
+ private Utils() {
+ // Hidden constructor.
+ }
+
+ /**
+ * Returns true if the string is null or 0-length.
+ *
+ * @param str the string to be examined
+ * @return true if str is null or zero length
+ */
+ static boolean isEmpty(CharSequence str) {
+ return str == null || str.length() == 0;
+ }
+
+ /**
+ * Returns true if a and b are equal, including if they are both null.
+ * Note: In platform versions 1.1 and earlier, this method only worked well if
+ * both the arguments were instances of String.
+ *
+ * @param a first CharSequence to check
+ * @param b second CharSequence to check
+ * @return true if a and b are equal
+ *
+ * NOTE: Logic slightly change due to strict policy on CI -
+ * "Inner assignments should be avoided"
+ */
+ static boolean equals(CharSequence a, CharSequence b) {
+ if (a == b) return true;
+ if (a != null && b != null) {
+ int length = a.length();
+ if (length == b.length()) {
+ if (a instanceof String && b instanceof String) {
+ return a.equals(b);
+ } else {
+ for (int i = 0; i < length; i++) {
+ if (a.charAt(i) != b.charAt(i)) return false;
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Copied from "android.util.Log.getStackTraceString()" in order to avoid usage of Android stack
+ * in unit tests.
+ *
+ * @return Stack trace in form of String
+ */
+ static String getStackTraceString(Throwable tr) {
+ if (tr == null) {
+ return "";
+ }
+
+ // This is to reduce the amount of log spew that apps do in the non-error
+ // condition of the network being unavailable.
+ Throwable t = tr;
+ while (t != null) {
+ if (t instanceof UnknownHostException) {
+ return "";
+ }
+ t = t.getCause();
+ }
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ tr.printStackTrace(pw);
+ pw.flush();
+ return sw.toString();
+ }
+
+ static String logLevel(int value) {
+ switch (value) {
+ case VERBOSE:
+ return "VERBOSE";
+ case DEBUG:
+ return "DEBUG";
+ case INFO:
+ return "INFO";
+ case WARN:
+ return "WARN";
+ case ERROR:
+ return "ERROR";
+ case ASSERT:
+ return "ASSERT";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ public static String toString(Object object) {
+ if (object == null) {
+ return "null";
+ }
+ if (!object.getClass().isArray()) {
+ return object.toString();
+ }
+ if (object instanceof boolean[]) {
+ return Arrays.toString((boolean[]) object);
+ }
+ if (object instanceof byte[]) {
+ return Arrays.toString((byte[]) object);
+ }
+ if (object instanceof char[]) {
+ return Arrays.toString((char[]) object);
+ }
+ if (object instanceof short[]) {
+ return Arrays.toString((short[]) object);
+ }
+ if (object instanceof int[]) {
+ return Arrays.toString((int[]) object);
+ }
+ if (object instanceof long[]) {
+ return Arrays.toString((long[]) object);
+ }
+ if (object instanceof float[]) {
+ return Arrays.toString((float[]) object);
+ }
+ if (object instanceof double[]) {
+ return Arrays.toString((double[]) object);
+ }
+ if (object instanceof Object[]) {
+ return Arrays.deepToString((Object[]) object);
+ }
+ return "Couldn't find a correct type for the object";
+ }
+
+ static T checkNotNull(@Nullable final T obj) {
+ if (obj == null) {
+ throw new NullPointerException();
+ }
+ return obj;
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSON.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSON.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac304a80e902d58f30b3952ff2b0f05a4794e720
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSON.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+class JSON {
+ /**
+ * Returns the input if it is a JSON-permissible value; throws otherwise.
+ */
+ static double checkDouble(double d) throws JSONException {
+ if (Double.isInfinite(d) || Double.isNaN(d)) {
+ throw new JSONException("Forbidden numeric value: " + d);
+ }
+ return d;
+ }
+
+ static Boolean toBoolean(Object value) {
+ if (value instanceof Boolean) {
+ return (Boolean) value;
+ } else if (value instanceof String) {
+ String stringValue = (String) value;
+ if ("true".equalsIgnoreCase(stringValue)) {
+ return true;
+ } else if ("false".equalsIgnoreCase(stringValue)) {
+ return false;
+ }
+ }
+ return null;
+ }
+
+ static Double toDouble(Object value) {
+ if (value instanceof Double) {
+ return (Double) value;
+ } else if (value instanceof Number) {
+ return ((Number) value).doubleValue();
+ } else if (value instanceof String) {
+ try {
+ return Double.valueOf((String) value);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return null;
+ }
+
+ static Integer toInteger(Object value) {
+ if (value instanceof Integer) {
+ return (Integer) value;
+ } else if (value instanceof Number) {
+ return ((Number) value).intValue();
+ } else if (value instanceof String) {
+ try {
+ return (int) Double.parseDouble((String) value);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return null;
+ }
+
+ static Long toLong(Object value) {
+ if (value instanceof Long) {
+ return (Long) value;
+ } else if (value instanceof Number) {
+ return ((Number) value).longValue();
+ } else if (value instanceof String) {
+ try {
+ return (long) Double.parseDouble((String) value);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return null;
+ }
+
+ static String toString(Object value) {
+ if (value instanceof String) {
+ return (String) value;
+ } else if (value != null) {
+ return String.valueOf(value);
+ }
+ return null;
+ }
+
+ public static JSONException typeMismatch(Object indexOrName, Object actual,
+ String requiredType) throws JSONException {
+ if (actual == null) {
+ throw new JSONException("Value at " + indexOrName + " is null.");
+ } else {
+ throw new JSONException("Value " + actual + " at " + indexOrName
+ + " of type " + actual.getClass().getName()
+ + " cannot be converted to " + requiredType);
+ }
+ }
+
+ public static JSONException typeMismatch(Object actual, String requiredType)
+ throws JSONException {
+ if (actual == null) {
+ throw new JSONException("Value is null.");
+ } else {
+ throw new JSONException("Value " + actual
+ + " of type " + actual.getClass().getName()
+ + " cannot be converted to " + requiredType);
+ }
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONArray.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONArray.java
new file mode 100644
index 0000000000000000000000000000000000000000..63d67ed6b3097f09e4a71d4847719cf0e89e835c
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONArray.java
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * A dense indexed sequence of values. Values may be any mix of
+ * {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
+ * Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
+ * Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
+ * infinities}, or of any type not listed here.
+ *
+ * {@code JSONArray} has the same type coercion behavior and
+ * optional/mandatory accessors as {@link JSONObject}. See that class'
+ * documentation for details.
+ *
+ *
Warning: this class represents null in two incompatible
+ * ways: the standard Java {@code null} reference, and the sentinel value {@link
+ * JSONObject#NULL}. In particular, {@code get} fails if the requested index
+ * holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
+ *
+ *
Instances of this class are not thread safe. Although this class is
+ * nonfinal, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overridable methods is not specified. See
+ * Effective Java Item 17, "Design and Document or inheritance or else
+ * prohibit it" for further information.
+ */
+public class JSONArray {
+
+ private final List values;
+
+ /**
+ * Creates a {@code JSONArray} with no values.
+ */
+ public JSONArray() {
+ values = new ArrayList();
+ }
+
+ /**
+ * Creates a new {@code JSONArray} by copying all values from the given
+ * collection.
+ *
+ * @param copyFrom a collection whose values are of supported types.
+ * Unsupported values are not permitted and will yield an array in an
+ * inconsistent state.
+ */
+ /* Accept a raw type for API compatibility */
+ public JSONArray(Collection copyFrom) {
+ this();
+ if (copyFrom != null) {
+ for (Iterator it = copyFrom.iterator(); it.hasNext(); ) {
+ put(JSONObject.wrap(it.next()));
+ }
+ }
+ }
+
+ /**
+ * Creates a new {@code JSONArray} with values from the next array in the
+ * tokener.
+ *
+ * @param readFrom a tokener whose nextValue() method will yield a
+ * {@code JSONArray}.
+ * @throws JSONException if the parse fails or doesn't yield a
+ * {@code JSONArray}.
+ */
+ public JSONArray(JSONTokener readFrom) throws JSONException {
+ /*
+ * Getting the parser to populate this could get tricky. Instead, just
+ * parse to temporary JSONArray and then steal the data from that.
+ */
+ Object object = readFrom.nextValue();
+ if (object instanceof JSONArray) {
+ values = ((JSONArray) object).values;
+ } else {
+ throw JSON.typeMismatch(object, "JSONArray");
+ }
+ }
+
+ /**
+ * Creates a new {@code JSONArray} with values from the JSON string.
+ *
+ * @param json a JSON-encoded string containing an array.
+ * @throws JSONException if the parse fails or doesn't yield a {@code
+ * JSONArray}.
+ */
+ public JSONArray(String json) throws JSONException {
+ this(new JSONTokener(json));
+ }
+
+ /**
+ * Creates a new {@code JSONArray} with values from the given primitive array.
+ */
+ public JSONArray(Object array) throws JSONException {
+ if (!array.getClass().isArray()) {
+ throw new JSONException("Not a primitive array: " + array.getClass());
+ }
+ final int length = Array.getLength(array);
+ values = new ArrayList(length);
+ for (int i = 0; i < length; ++i) {
+ put(JSONObject.wrap(Array.get(array, i)));
+ }
+ }
+
+ /**
+ * Returns the number of values in this array.
+ */
+ public int length() {
+ return values.size();
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @return this array.
+ */
+ public JSONArray put(boolean value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * @return this array.
+ */
+ public JSONArray put(double value) throws JSONException {
+ values.add(JSON.checkDouble(value));
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @return this array.
+ */
+ public JSONArray put(int value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @return this array.
+ */
+ public JSONArray put(long value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Appends {@code value} to the end of this array.
+ *
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+ * not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+ * infinities}. Unsupported values are not permitted and will cause the
+ * array to be in an inconsistent state.
+ * @return this array.
+ */
+ public JSONArray put(Object value) {
+ values.add(value);
+ return this;
+ }
+
+ /**
+ * Same as {@link #put}, with added validity checks.
+ */
+ void checkedPut(Object value) throws JSONException {
+ if (value instanceof Number) {
+ JSON.checkDouble(((Number) value).doubleValue());
+ }
+
+ put(value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @return this array.
+ */
+ public JSONArray put(int index, boolean value) throws JSONException {
+ return put(index, (Boolean) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * @return this array.
+ */
+ public JSONArray put(int index, double value) throws JSONException {
+ return put(index, (Double) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @return this array.
+ */
+ public JSONArray put(int index, int value) throws JSONException {
+ return put(index, (Integer) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @return this array.
+ */
+ public JSONArray put(int index, long value) throws JSONException {
+ return put(index, (Long) value);
+ }
+
+ /**
+ * Sets the value at {@code index} to {@code value}, null padding this array
+ * to the required length if necessary. If a value already exists at {@code
+ * index}, it will be replaced.
+ *
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+ * not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+ * infinities}.
+ * @return this array.
+ */
+ public JSONArray put(int index, Object value) throws JSONException {
+ if (value instanceof Number) {
+ // deviate from the original by checking all Numbers, not just floats & doubles
+ JSON.checkDouble(((Number) value).doubleValue());
+ }
+ while (values.size() <= index) {
+ values.add(null);
+ }
+ values.set(index, value);
+ return this;
+ }
+
+ /**
+ * Returns true if this array has no value at {@code index}, or if its value
+ * is the {@code null} reference or {@link JSONObject#NULL}.
+ */
+ public boolean isNull(int index) {
+ Object value = opt(index);
+ return value == null || value == JSONObject.NULL;
+ }
+
+ /**
+ * Returns the value at {@code index}.
+ *
+ * @throws JSONException if this array has no value at {@code index}, or if
+ * that value is the {@code null} reference. This method returns
+ * normally if the value is {@code JSONObject#NULL}.
+ */
+ public Object get(int index) throws JSONException {
+ try {
+ Object value = values.get(index);
+ if (value == null) {
+ throw new JSONException("Value at " + index + " is null.");
+ }
+ return value;
+ } catch (IndexOutOfBoundsException e) {
+ throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")", e);
+ }
+ }
+
+ /**
+ * Returns the value at {@code index}, or null if the array has no value
+ * at {@code index}.
+ */
+ public Object opt(int index) {
+ if (index < 0 || index >= values.size()) {
+ return null;
+ }
+ return values.get(index);
+ }
+
+ /**
+ * Removes and returns the value at {@code index}, or null if the array has no value
+ * at {@code index}.
+ */
+ public Object remove(int index) {
+ if (index < 0 || index >= values.size()) {
+ return null;
+ }
+ return values.remove(index);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a boolean or can
+ * be coerced to a boolean.
+ *
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a boolean.
+ */
+ public boolean getBoolean(int index) throws JSONException {
+ Object object = get(index);
+ Boolean result = JSON.toBoolean(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "boolean");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a boolean or can
+ * be coerced to a boolean. Returns false otherwise.
+ */
+ public boolean optBoolean(int index) {
+ return optBoolean(index, false);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a boolean or can
+ * be coerced to a boolean. Returns {@code fallback} otherwise.
+ */
+ public boolean optBoolean(int index, boolean fallback) {
+ Object object = opt(index);
+ Boolean result = JSON.toBoolean(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a double or can
+ * be coerced to a double.
+ *
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a double.
+ */
+ public double getDouble(int index) throws JSONException {
+ Object object = get(index);
+ Double result = JSON.toDouble(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "double");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a double or can
+ * be coerced to a double. Returns {@code NaN} otherwise.
+ */
+ public double optDouble(int index) {
+ return optDouble(index, Double.NaN);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a double or can
+ * be coerced to a double. Returns {@code fallback} otherwise.
+ */
+ public double optDouble(int index, double fallback) {
+ Object object = opt(index);
+ Double result = JSON.toDouble(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is an int or
+ * can be coerced to an int.
+ *
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a int.
+ */
+ public int getInt(int index) throws JSONException {
+ Object object = get(index);
+ Integer result = JSON.toInteger(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "int");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is an int or
+ * can be coerced to an int. Returns 0 otherwise.
+ */
+ public int optInt(int index) {
+ return optInt(index, 0);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is an int or
+ * can be coerced to an int. Returns {@code fallback} otherwise.
+ */
+ public int optInt(int index, int fallback) {
+ Object object = opt(index);
+ Integer result = JSON.toInteger(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a long or
+ * can be coerced to a long.
+ *
+ * @throws JSONException if the value at {@code index} doesn't exist or
+ * cannot be coerced to a long.
+ */
+ public long getLong(int index) throws JSONException {
+ Object object = get(index);
+ Long result = JSON.toLong(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "long");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a long or
+ * can be coerced to a long. Returns 0 otherwise.
+ */
+ public long optLong(int index) {
+ return optLong(index, 0L);
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a long or
+ * can be coerced to a long. Returns {@code fallback} otherwise.
+ */
+ public long optLong(int index, long fallback) {
+ Object object = opt(index);
+ Long result = JSON.toLong(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists, coercing it if
+ * necessary.
+ *
+ * @throws JSONException if no such value exists.
+ */
+ public String getString(int index) throws JSONException {
+ Object object = get(index);
+ String result = JSON.toString(object);
+ if (result == null) {
+ throw JSON.typeMismatch(index, object, "String");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists, coercing it if
+ * necessary. Returns the empty string if no such value exists.
+ */
+ public String optString(int index) {
+ return optString(index, "");
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists, coercing it if
+ * necessary. Returns {@code fallback} if no such value exists.
+ */
+ public String optString(int index, String fallback) {
+ Object object = opt(index);
+ String result = JSON.toString(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONArray}.
+ *
+ * @throws JSONException if the value doesn't exist or is not a {@code
+ * JSONArray}.
+ */
+ public JSONArray getJSONArray(int index) throws JSONException {
+ Object object = get(index);
+ if (object instanceof JSONArray) {
+ return (JSONArray) object;
+ } else {
+ throw JSON.typeMismatch(index, object, "JSONArray");
+ }
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONArray}. Returns null otherwise.
+ */
+ public JSONArray optJSONArray(int index) {
+ Object object = opt(index);
+ return object instanceof JSONArray ? (JSONArray) object : null;
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONObject}.
+ *
+ * @throws JSONException if the value doesn't exist or is not a {@code
+ * JSONObject}.
+ */
+ public JSONObject getJSONObject(int index) throws JSONException {
+ Object object = get(index);
+ if (object instanceof JSONObject) {
+ return (JSONObject) object;
+ } else {
+ throw JSON.typeMismatch(index, object, "JSONObject");
+ }
+ }
+
+ /**
+ * Returns the value at {@code index} if it exists and is a {@code
+ * JSONObject}. Returns null otherwise.
+ */
+ public JSONObject optJSONObject(int index) {
+ Object object = opt(index);
+ return object instanceof JSONObject ? (JSONObject) object : null;
+ }
+
+ /**
+ * Returns a new object whose values are the values in this array, and whose
+ * names are the values in {@code names}. Names and values are paired up by
+ * index from 0 through to the shorter array's length. Names that are not
+ * strings will be coerced to strings. This method returns null if either
+ * array is empty.
+ */
+ public JSONObject toJSONObject(JSONArray names) throws JSONException {
+ JSONObject result = new JSONObject();
+ int length = Math.min(names.length(), values.size());
+ if (length == 0) {
+ return null;
+ }
+ for (int i = 0; i < length; i++) {
+ String name = JSON.toString(names.opt(i));
+ result.put(name, opt(i));
+ }
+ return result;
+ }
+
+ /**
+ * Returns a new string by alternating this array's values with {@code
+ * separator}. This array's string values are quoted and have their special
+ * characters escaped. For example, the array containing the strings '12"
+ * pizza', 'taco' and 'soda' joined on '+' returns this:
+ * "12\" pizza"+"taco"+"soda"
+ */
+ public String join(String separator) throws JSONException {
+ JSONStringer stringer = new JSONStringer();
+ stringer.open(JSONStringer.Scope.NULL, "");
+ for (int i = 0, size = values.size(); i < size; i++) {
+ if (i > 0) {
+ stringer.out.append(separator);
+ }
+ stringer.value(values.get(i));
+ }
+ stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+ return stringer.out.toString();
+ }
+
+ /**
+ * Encodes this array as a compact JSON string, such as:
+ * [94043,90210]
+ */
+ @Override
+ public String toString() {
+ try {
+ JSONStringer stringer = new JSONStringer();
+ writeTo(stringer);
+ return stringer.toString();
+ } catch (JSONException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Encodes this array as a human readable JSON string for debugging, such
+ * as:
+ *
+ * [
+ * 94043,
+ * 90210
+ * ]
+ *
+ * @param indentSpaces the number of spaces to indent for each level of
+ * nesting.
+ */
+ public String toString(int indentSpaces) throws JSONException {
+ JSONStringer stringer = new JSONStringer(indentSpaces);
+ writeTo(stringer);
+ return stringer.toString();
+ }
+
+
+ void writeTo(JSONStringer stringer) throws JSONException {
+ stringer.array();
+ for (Object value : values) {
+ stringer.value(value);
+ }
+ stringer.endArray();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
+ }
+
+ @Override
+ public int hashCode() {
+ // diverge from the original, which doesn't implement hashCode
+ return values.hashCode();
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONException.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONException.java
new file mode 100644
index 0000000000000000000000000000000000000000..05e1dddc9aa4666dc89175d144288f9d9aa08ce4
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * Thrown to indicate a problem with the JSON API. Such problems include:
+ *
+ * Attempts to parse or construct malformed documents
+ * Use of null as a name
+ * Use of numeric types not available to JSON, such as {@link
+ * Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
+ * Lookups using an out of range index or nonexistent name
+ * Type mismatches on lookups
+ *
+ *
+ * Although this is a checked exception, it is rarely recoverable. Most
+ * callers should simply wrap this exception in an unchecked exception and
+ * rethrow:
+ *
public JSONArray toJSONObject() {
+ * try {
+ * JSONObject result = new JSONObject();
+ * ...
+ * } catch (JSONException e) {
+ * throw new RuntimeException(e);
+ * }
+ * }
+ */
+public class JSONException extends Exception {
+
+ public JSONException(String s) {
+ super(s);
+ }
+
+ public JSONException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public JSONException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONObject.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONObject.java
new file mode 100644
index 0000000000000000000000000000000000000000..587dd4302e92984360ed39646190aabcc645dc5d
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONObject.java
@@ -0,0 +1,855 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import java.util.*;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * A modifiable set of name/value mappings. Names are unique, non-null strings.
+ * Values may be any mix of {@link JSONObject JSONObjects}, {@link JSONArray
+ * JSONArrays}, Strings, Booleans, Integers, Longs, Doubles or {@link #NULL}.
+ * Values may not be {@code null}, {@link Double#isNaN() NaNs}, {@link
+ * Double#isInfinite() infinities}, or of any type not listed here.
+ *
+ * This class can coerce values to another type when requested.
+ *
+ *
+ * This class can look up both mandatory and optional values:
+ *
+ * Use getType () to retrieve a mandatory value. This
+ * fails with a {@code JSONException} if the requested name has no value
+ * or if the value cannot be coerced to the requested type.
+ * Use optType () to retrieve an optional value. This
+ * returns a system- or user-supplied default if the requested name has no
+ * value or if the value cannot be coerced to the requested type.
+ *
+ *
+ * Warning: this class represents null in two incompatible
+ * ways: the standard Java {@code null} reference, and the sentinel value {@link
+ * JSONObject#NULL}. In particular, calling {@code put(name, null)} removes the
+ * named entry from the object but {@code put(name, JSONObject.NULL)} stores an
+ * entry whose value is {@code JSONObject.NULL}.
+ *
+ *
Instances of this class are not thread safe. Although this class is
+ * nonfinal, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overrideable methods is not specified. See
+ * Effective Java Item 17, "Design and Document or inheritance or else
+ * prohibit it" for further information.
+ */
+public class JSONObject {
+
+ private static final Double NEGATIVE_ZERO = -0d;
+
+ /**
+ * A sentinel value used to explicitly define a name with no value. Unlike
+ * {@code null}, names with this value:
+ *
+ * show up in the {@link #names} array
+ * show up in the {@link #keys} iterator
+ * return {@code true} for {@link #has(String)}
+ * do not throw on {@link #get(String)}
+ * are included in the encoded JSON string.
+ *
+ *
+ * This value violates the general contract of {@link Object#equals} by
+ * returning true when compared to {@code null}. Its {@link #toString}
+ * method returns "null".
+ */
+ public static final Object NULL = new Object() {
+ @Override
+ public boolean equals(Object o) {
+ return o == this || o == null; // API specifies this broken equals implementation
+ }
+
+ // at least make the broken equals(null) consistent with Objects.hashCode(null).
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(null);
+ }
+
+ @Override
+ public String toString() {
+ return "null";
+ }
+ };
+
+
+ private final LinkedHashMap nameValuePairs;
+
+ /**
+ * Creates a {@code JSONObject} with no name/value mappings.
+ */
+ public JSONObject() {
+ nameValuePairs = new LinkedHashMap();
+ }
+
+ /**
+ * Creates a new {@code JSONObject} by copying all name/value mappings from
+ * the given map.
+ *
+ * @param copyFrom a map whose keys are of type {@link String} and whose
+ * values are of supported types.
+ * @throws NullPointerException if any of the map's keys are null.
+ */
+ /* (accept a raw type for API compatibility) */
+ public JSONObject(Map copyFrom) {
+ this();
+ Map, ?> contentsTyped = (Map, ?>) copyFrom;
+ for (Map.Entry, ?> entry : contentsTyped.entrySet()) {
+ /*
+ * Deviate from the original by checking that keys are non-null and
+ * of the proper type. (We still defer validating the values).
+ */
+ String key = (String) entry.getKey();
+ if (key == null) {
+ throw new NullPointerException("key == null");
+ }
+ nameValuePairs.put(key, wrap(entry.getValue()));
+ }
+ }
+
+ /**
+ * Creates a new {@code JSONObject} with name/value mappings from the next
+ * object in the tokener.
+ *
+ * @param readFrom a tokener whose nextValue() method will yield a
+ * {@code JSONObject}.
+ * @throws JSONException if the parse fails or doesn't yield a
+ * {@code JSONObject}.
+ */
+ public JSONObject(JSONTokener readFrom) throws JSONException {
+ /*
+ * Getting the parser to populate this could get tricky. Instead, just
+ * parse to temporary JSONObject and then steal the data from that.
+ */
+ Object object = readFrom.nextValue();
+ if (object instanceof JSONObject) {
+ this.nameValuePairs = ((JSONObject) object).nameValuePairs;
+ } else {
+ throw JSON.typeMismatch(object, "JSONObject");
+ }
+ }
+
+ /**
+ * Creates a new {@code JSONObject} with name/value mappings from the JSON
+ * string.
+ *
+ * @param json a JSON-encoded string containing an object.
+ * @throws JSONException if the parse fails or doesn't yield a {@code
+ * JSONObject}.
+ */
+ public JSONObject(String json) throws JSONException {
+ this(new JSONTokener(json));
+ }
+
+ /**
+ * Creates a new {@code JSONObject} by copying mappings for the listed names
+ * from the given object. Names that aren't present in {@code copyFrom} will
+ * be skipped.
+ */
+ public JSONObject(JSONObject copyFrom, String[] names) throws JSONException {
+ this();
+ for (String name : names) {
+ Object value = copyFrom.opt(name);
+ if (value != null) {
+ nameValuePairs.put(name, value);
+ }
+ }
+ }
+
+ /**
+ * Returns the number of name/value mappings in this object.
+ */
+ public int length() {
+ return nameValuePairs.size();
+ }
+
+ /**
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
+ *
+ * @return this object.
+ */
+
+ public JSONObject put(String name, boolean value) throws JSONException {
+ nameValuePairs.put(checkName(name), value);
+ return this;
+ }
+
+ /**
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
+ *
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * @return this object.
+ */
+
+ public JSONObject put(String name, double value) throws JSONException {
+ nameValuePairs.put(checkName(name), JSON.checkDouble(value));
+ return this;
+ }
+
+ /**
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
+ *
+ * @return this object.
+ */
+
+ public JSONObject put(String name, int value) throws JSONException {
+ nameValuePairs.put(checkName(name), value);
+ return this;
+ }
+
+ /**
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name.
+ *
+ * @return this object.
+ */
+
+ public JSONObject put(String name, long value) throws JSONException {
+ nameValuePairs.put(checkName(name), value);
+ return this;
+ }
+
+ /**
+ * Maps {@code name} to {@code value}, clobbering any existing name/value
+ * mapping with the same name. If the value is {@code null}, any existing
+ * mapping for {@code name} is removed.
+ *
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double, {@link #NULL}, or {@code null}. May not be
+ * {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+ * infinities}.
+ * @return this object.
+ */
+
+ public JSONObject put(String name, Object value) throws JSONException {
+ if (value == null) {
+ nameValuePairs.remove(name);
+ return this;
+ }
+ if (value instanceof Number) {
+ // deviate from the original by checking all Numbers, not just floats & doubles
+ JSON.checkDouble(((Number) value).doubleValue());
+ }
+ nameValuePairs.put(checkName(name), value);
+ return this;
+ }
+
+ /**
+ * Equivalent to {@code put(name, value)} when both parameters are non-null;
+ * does nothing otherwise.
+ */
+
+ public JSONObject putOpt(String name, Object value) throws JSONException {
+ if (name == null || value == null) {
+ return this;
+ }
+ return put(name, value);
+ }
+
+ /**
+ * Appends {@code value} to the array already mapped to {@code name}. If
+ * this object has no mapping for {@code name}, this inserts a new mapping.
+ * If the mapping exists but its value is not an array, the existing
+ * and new values are inserted in order into a new array which is itself
+ * mapped to {@code name}. In aggregate, this allows values to be added to a
+ * mapping one at a time.
+ *
+ * Note that {@code append(String, Object)} provides better semantics.
+ * In particular, the mapping for {@code name} will always be a
+ * {@link JSONArray}. Using {@code accumulate} will result in either a
+ * {@link JSONArray} or a mapping whose type is the type of {@code value}
+ * depending on the number of calls to it.
+ *
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double, {@link #NULL} or null. May not be {@link
+ * Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
+ */
+ // TODO: Change {@code append) to {@link #append} when append is
+ // unhidden.
+ public JSONObject accumulate(String name, Object value) throws JSONException {
+ Object current = nameValuePairs.get(checkName(name));
+ if (current == null) {
+ return put(name, value);
+ }
+
+ if (current instanceof JSONArray) {
+ JSONArray array = (JSONArray) current;
+ array.checkedPut(value);
+ } else {
+ JSONArray array = new JSONArray();
+ array.checkedPut(current);
+ array.checkedPut(value);
+ nameValuePairs.put(name, array);
+ }
+ return this;
+ }
+
+ /**
+ * Appends values to the array mapped to {@code name}. A new {@link JSONArray}
+ * mapping for {@code name} will be inserted if no mapping exists. If the existing
+ * mapping for {@code name} is not a {@link JSONArray}, a {@link JSONException}
+ * will be thrown.
+ *
+ * @throws JSONException if {@code name} is {@code null} or if the mapping for
+ * {@code name} is non-null and is not a {@link JSONArray}.
+ * @hide
+ */
+
+ public JSONObject append(String name, Object value) throws JSONException {
+ Object current = nameValuePairs.get(checkName(name));
+
+ final JSONArray array;
+ if (current instanceof JSONArray) {
+ array = (JSONArray) current;
+ } else if (current == null) {
+ JSONArray newArray = new JSONArray();
+ nameValuePairs.put(name, newArray);
+ array = newArray;
+ } else {
+ throw new JSONException("Key " + name + " is not a JSONArray");
+ }
+
+ array.checkedPut(value);
+
+ return this;
+ }
+
+
+ String checkName(String name) throws JSONException {
+ if (name == null) {
+ throw new JSONException("Names must be non-null");
+ }
+ return name;
+ }
+
+ /**
+ * Removes the named mapping if it exists; does nothing otherwise.
+ *
+ * @return the value previously mapped by {@code name}, or null if there was
+ * no such mapping.
+ */
+
+ public Object remove(String name) {
+ return nameValuePairs.remove(name);
+ }
+
+ /**
+ * Returns true if this object has no mapping for {@code name} or if it has
+ * a mapping whose value is {@link #NULL}.
+ */
+ public boolean isNull(String name) {
+ Object value = nameValuePairs.get(name);
+ return value == null || value == NULL;
+ }
+
+ /**
+ * Returns true if this object has a mapping for {@code name}. The mapping
+ * may be {@link #NULL}.
+ */
+ public boolean has(String name) {
+ return nameValuePairs.containsKey(name);
+ }
+
+ /**
+ * Returns the value mapped by {@code name}, or throws if no such mapping exists.
+ *
+ * @throws JSONException if no such mapping exists.
+ */
+
+ public Object get(String name) throws JSONException {
+ Object result = nameValuePairs.get(name);
+ if (result == null) {
+ throw new JSONException("No value for " + name);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value mapped by {@code name}, or null if no such mapping
+ * exists.
+ */
+
+ public Object opt(String name) {
+ return nameValuePairs.get(name);
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a boolean or
+ * can be coerced to a boolean, or throws otherwise.
+ *
+ * @throws JSONException if the mapping doesn't exist or cannot be coerced
+ * to a boolean.
+ */
+ public boolean getBoolean(String name) throws JSONException {
+ Object object = get(name);
+ Boolean result = JSON.toBoolean(object);
+ if (result == null) {
+ throw JSON.typeMismatch(name, object, "boolean");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a boolean or
+ * can be coerced to a boolean, or false otherwise.
+ */
+ public boolean optBoolean(String name) {
+ return optBoolean(name, false);
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a boolean or
+ * can be coerced to a boolean, or {@code fallback} otherwise.
+ */
+ public boolean optBoolean(String name, boolean fallback) {
+ Object object = opt(name);
+ Boolean result = JSON.toBoolean(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a double or
+ * can be coerced to a double, or throws otherwise.
+ *
+ * @throws JSONException if the mapping doesn't exist or cannot be coerced
+ * to a double.
+ */
+ public double getDouble(String name) throws JSONException {
+ Object object = get(name);
+ Double result = JSON.toDouble(object);
+ if (result == null) {
+ throw JSON.typeMismatch(name, object, "double");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a double or
+ * can be coerced to a double, or {@code NaN} otherwise.
+ */
+ public double optDouble(String name) {
+ return optDouble(name, Double.NaN);
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a double or
+ * can be coerced to a double, or {@code fallback} otherwise.
+ */
+ public double optDouble(String name, double fallback) {
+ Object object = opt(name);
+ Double result = JSON.toDouble(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is an int or
+ * can be coerced to an int, or throws otherwise.
+ *
+ * @throws JSONException if the mapping doesn't exist or cannot be coerced
+ * to an int.
+ */
+ public int getInt(String name) throws JSONException {
+ Object object = get(name);
+ Integer result = JSON.toInteger(object);
+ if (result == null) {
+ throw JSON.typeMismatch(name, object, "int");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is an int or
+ * can be coerced to an int, or 0 otherwise.
+ */
+ public int optInt(String name) {
+ return optInt(name, 0);
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is an int or
+ * can be coerced to an int, or {@code fallback} otherwise.
+ */
+ public int optInt(String name, int fallback) {
+ Object object = opt(name);
+ Integer result = JSON.toInteger(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a long or
+ * can be coerced to a long, or throws otherwise.
+ * Note that JSON represents numbers as doubles,
+ * so this is lossy ; use strings to transfer numbers via JSON.
+ *
+ * @throws JSONException if the mapping doesn't exist or cannot be coerced
+ * to a long.
+ */
+ public long getLong(String name) throws JSONException {
+ Object object = get(name);
+ Long result = JSON.toLong(object);
+ if (result == null) {
+ throw JSON.typeMismatch(name, object, "long");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a long or
+ * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
+ * so this is lossy ; use strings to transfer numbers via JSON.
+ */
+ public long optLong(String name) {
+ return optLong(name, 0L);
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a long or
+ * can be coerced to a long, or {@code fallback} otherwise. Note that JSON represents
+ * numbers as doubles, so this is lossy ; use strings to transfer
+ * numbers via JSON.
+ */
+ public long optLong(String name, long fallback) {
+ Object object = opt(name);
+ Long result = JSON.toLong(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists, coercing it if
+ * necessary, or throws if no such mapping exists.
+ *
+ * @throws JSONException if no such mapping exists.
+ */
+
+ public String getString(String name) throws JSONException {
+ Object object = get(name);
+ String result = JSON.toString(object);
+ if (result == null) {
+ throw JSON.typeMismatch(name, object, "String");
+ }
+ return result;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists, coercing it if
+ * necessary, or the empty string if no such mapping exists.
+ */
+
+ public String optString(String name) {
+ return optString(name, "");
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists, coercing it if
+ * necessary, or {@code fallback} if no such mapping exists.
+ */
+
+ public String optString(String name, String fallback) {
+ Object object = opt(name);
+ String result = JSON.toString(object);
+ return result != null ? result : fallback;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a {@code
+ * JSONArray}, or throws otherwise.
+ *
+ * @throws JSONException if the mapping doesn't exist or is not a {@code
+ * JSONArray}.
+ */
+
+ public JSONArray getJSONArray(String name) throws JSONException {
+ Object object = get(name);
+ if (object instanceof JSONArray) {
+ return (JSONArray) object;
+ } else {
+ throw JSON.typeMismatch(name, object, "JSONArray");
+ }
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a {@code
+ * JSONArray}, or null otherwise.
+ */
+
+ public JSONArray optJSONArray(String name) {
+ Object object = opt(name);
+ return object instanceof JSONArray ? (JSONArray) object : null;
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a {@code
+ * JSONObject}, or throws otherwise.
+ *
+ * @throws JSONException if the mapping doesn't exist or is not a {@code
+ * JSONObject}.
+ */
+
+ public JSONObject getJSONObject(String name) throws JSONException {
+ Object object = get(name);
+ if (object instanceof JSONObject) {
+ return (JSONObject) object;
+ } else {
+ throw JSON.typeMismatch(name, object, "JSONObject");
+ }
+ }
+
+ /**
+ * Returns the value mapped by {@code name} if it exists and is a {@code
+ * JSONObject}, or null otherwise.
+ */
+
+ public JSONObject optJSONObject(String name) {
+ Object object = opt(name);
+ return object instanceof JSONObject ? (JSONObject) object : null;
+ }
+
+ /**
+ * Returns an array with the values corresponding to {@code names}. The
+ * array contains null for names that aren't mapped. This method returns
+ * null if {@code names} is either null or empty.
+ */
+
+ public JSONArray toJSONArray(JSONArray names) throws JSONException {
+ JSONArray result = new JSONArray();
+ if (names == null) {
+ return null;
+ }
+ int length = names.length();
+ if (length == 0) {
+ return null;
+ }
+ for (int i = 0; i < length; i++) {
+ String name = JSON.toString(names.opt(i));
+ result.put(opt(name));
+ }
+ return result;
+ }
+
+ /**
+ * Returns an iterator of the {@code String} names in this object. The
+ * returned iterator supports {@link Iterator#remove() remove}, which will
+ * remove the corresponding mapping from this object. If this object is
+ * modified after the iterator is returned, the iterator's behavior is
+ * undefined. The order of the keys is undefined.
+ */
+
+ public Iterator keys() {
+ return nameValuePairs.keySet().iterator();
+ }
+
+ /**
+ * Returns the set of {@code String} names in this object. The returned set
+ * is a view of the keys in this object. {@link Set#remove(Object)} will remove
+ * the corresponding mapping from this object and set iterator behaviour
+ * is undefined if this object is modified after it is returned.
+ *
+ * See {@link #keys()}.
+ *
+ * @hide.
+ */
+ public Set keySet() {
+ return nameValuePairs.keySet();
+ }
+
+ /**
+ * Returns an array containing the string names in this object. This method
+ * returns null if this object contains no mappings.
+ */
+
+ public JSONArray names() {
+ return nameValuePairs.isEmpty()
+ ? null
+ : new JSONArray(new ArrayList(nameValuePairs.keySet()));
+ }
+
+ /**
+ * Encodes this object as a compact JSON string, such as:
+ * {"query":"Pizza","locations":[94043,90210]}
+ */
+ @Override
+
+ public String toString() {
+ try {
+ JSONStringer stringer = new JSONStringer();
+ writeTo(stringer);
+ return stringer.toString();
+ } catch (JSONException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Encodes this object as a human readable JSON string for debugging, such
+ * as:
+ *
+ * {
+ * "query": "Pizza",
+ * "locations": [
+ * 94043,
+ * 90210
+ * ]
+ * }
+ *
+ * @param indentSpaces the number of spaces to indent for each level of
+ * nesting.
+ */
+
+ public String toString(int indentSpaces) throws JSONException {
+ JSONStringer stringer = new JSONStringer(indentSpaces);
+ writeTo(stringer);
+ return stringer.toString();
+ }
+
+
+ void writeTo(JSONStringer stringer) throws JSONException {
+ stringer.object();
+ for (Map.Entry entry : nameValuePairs.entrySet()) {
+ stringer.key(entry.getKey()).value(entry.getValue());
+ }
+ stringer.endObject();
+ }
+
+ /**
+ * Encodes the number as a JSON string.
+ *
+ * @param number a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ */
+
+ public static String numberToString(Number number) throws JSONException {
+ if (number == null) {
+ throw new JSONException("Number must be non-null");
+ }
+
+ double doubleValue = number.doubleValue();
+ JSON.checkDouble(doubleValue);
+
+ // the original returns "-0" instead of "-0.0" for negative zero
+ if (number.equals(NEGATIVE_ZERO)) {
+ return "-0";
+ }
+
+ long longValue = number.longValue();
+ if (doubleValue == (double) longValue) {
+ return Long.toString(longValue);
+ }
+
+ return number.toString();
+ }
+
+ /**
+ * Encodes {@code data} as a JSON string. This applies quotes and any
+ * necessary character escaping.
+ *
+ * @param data the string to encode. Null will be interpreted as an empty
+ * string.
+ */
+
+ public static String quote(String data) {
+ if (data == null) {
+ return "\"\"";
+ }
+ try {
+ JSONStringer stringer = new JSONStringer();
+ stringer.open(JSONStringer.Scope.NULL, "");
+ stringer.value(data);
+ stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+ return stringer.toString();
+ } catch (JSONException e) {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Wraps the given object if necessary.
+ *
+ * If the object is null or , returns {@link #NULL}.
+ * If the object is a {@code JSONArray} or {@code JSONObject}, no wrapping is necessary.
+ * If the object is {@code NULL}, no wrapping is necessary.
+ * If the object is an array or {@code Collection}, returns an equivalent {@code JSONArray}.
+ * If the object is a {@code Map}, returns an equivalent {@code JSONObject}.
+ * If the object is a primitive wrapper type or {@code String}, returns the object.
+ * Otherwise if the object is from a {@code java} package, returns the result of {@code toString}.
+ * If wrapping fails, returns null.
+ */
+
+ public static Object wrap(Object o) {
+ if (o == null) {
+ return NULL;
+ }
+ if (o instanceof JSONArray || o instanceof JSONObject) {
+ return o;
+ }
+ if (o.equals(NULL)) {
+ return o;
+ }
+ try {
+ if (o instanceof Collection) {
+ return new JSONArray((Collection) o);
+ } else if (o.getClass().isArray()) {
+ return new JSONArray(o);
+ }
+ if (o instanceof Map) {
+ return new JSONObject((Map) o);
+ }
+ if (o instanceof Boolean ||
+ o instanceof Byte ||
+ o instanceof Character ||
+ o instanceof Double ||
+ o instanceof Float ||
+ o instanceof Integer ||
+ o instanceof Long ||
+ o instanceof Short ||
+ o instanceof String) {
+ return o;
+ }
+ if (o.getClass().getPackage().getName().startsWith("java.")) {
+ return o.toString();
+ }
+ } catch (Exception ignored) {
+ }
+ return null;
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONStringer.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONStringer.java
new file mode 100644
index 0000000000000000000000000000000000000000..668e1c75dfa90ee2bcf2d8f01569bbcb27f9484d
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONStringer.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most
+ * application developers should use those methods directly and disregard this
+ * API. For example:
+ * JSONObject object = ...
+ * String json = object.toString();
+ *
+ * Stringers only encode well-formed JSON strings. In particular:
+ *
+ * The stringer must have exactly one top-level array or object.
+ * Lexical scopes must be balanced: every call to {@link #array} must
+ * have a matching call to {@link #endArray} and every call to {@link
+ * #object} must have a matching call to {@link #endObject}.
+ * Arrays may not contain keys (property names).
+ * Objects must alternate keys (property names) and values.
+ * Values are inserted with either literal {@link #value(Object) value}
+ * calls, or by nesting arrays or objects.
+ *
+ * Calls that would result in a malformed JSON string will fail with a
+ * {@link JSONException}.
+ *
+ * This class provides no facility for pretty-printing (ie. indenting)
+ * output. To encode indented output, use {@link JSONObject#toString(int)} or
+ * {@link JSONArray#toString(int)}.
+ *
+ *
Some implementations of the API support at most 20 levels of nesting.
+ * Attempts to create more than 20 levels of nesting may fail with a {@link
+ * JSONException}.
+ *
+ *
Each stringer may be used to encode a single top level value. Instances of
+ * this class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See Effective Java
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
+ */
+public class JSONStringer {
+
+ /**
+ * The output data, containing at most one top-level array or object.
+ */
+ final StringBuilder out = new StringBuilder();
+
+ /**
+ * Lexical scoping elements within this stringer, necessary to insert the
+ * appropriate separator characters (ie. commas and colons) and to detect
+ * nesting errors.
+ */
+ enum Scope {
+
+ /**
+ * An array with no elements requires no separators or newlines before
+ * it is closed.
+ */
+ EMPTY_ARRAY,
+
+ /**
+ * A array with at least one value requires a comma and newline before
+ * the next element.
+ */
+ NONEMPTY_ARRAY,
+
+ /**
+ * An object with no keys or values requires no separators or newlines
+ * before it is closed.
+ */
+ EMPTY_OBJECT,
+
+ /**
+ * An object whose most recent element is a key. The next element must
+ * be a value.
+ */
+ DANGLING_KEY,
+
+ /**
+ * An object with at least one name/value pair requires a comma and
+ * newline before the next element.
+ */
+ NONEMPTY_OBJECT,
+
+ /**
+ * A special bracketless array needed by JSONStringer.join() and
+ * JSONObject.quote() only. Not used for JSON encoding.
+ */
+ NULL,
+ }
+
+ /**
+ * Unlike the original implementation, this stack isn't limited to 20
+ * levels of nesting.
+ */
+
+ private final List stack = new ArrayList();
+
+ /**
+ * A string containing a full set of spaces for a single level of
+ * indentation, or null for no pretty printing.
+ */
+
+ private final String indent;
+
+ public JSONStringer() {
+ indent = null;
+ }
+
+
+ JSONStringer(int indentSpaces) {
+ char[] indentChars = new char[indentSpaces];
+ Arrays.fill(indentChars, ' ');
+ indent = new String(indentChars);
+ }
+
+ /**
+ * Begins encoding a new array. Each call to this method must be paired with
+ * a call to {@link #endArray}.
+ *
+ * @return this stringer.
+ */
+ public JSONStringer array() throws JSONException {
+ return open(Scope.EMPTY_ARRAY, "[");
+ }
+
+ /**
+ * Ends encoding the current array.
+ *
+ * @return this stringer.
+ */
+ public JSONStringer endArray() throws JSONException {
+ return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
+ }
+
+ /**
+ * Begins encoding a new object. Each call to this method must be paired
+ * with a call to {@link #endObject}.
+ *
+ * @return this stringer.
+ */
+ public JSONStringer object() throws JSONException {
+ return open(Scope.EMPTY_OBJECT, "{");
+ }
+
+ /**
+ * Ends encoding the current object.
+ *
+ * @return this stringer.
+ */
+ public JSONStringer endObject() throws JSONException {
+ return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+ }
+
+ /**
+ * Enters a new scope by appending any necessary whitespace and the given
+ * bracket.
+ */
+
+ JSONStringer open(Scope empty, String openBracket) throws JSONException {
+ if (stack.isEmpty() && out.length() > 0) {
+ throw new JSONException("Nesting problem: multiple top-level roots");
+ }
+ beforeValue();
+ stack.add(empty);
+ out.append(openBracket);
+ return this;
+ }
+
+ /**
+ * Closes the current scope by appending any necessary whitespace and the
+ * given bracket.
+ */
+
+ JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
+ Scope context = peek();
+ if (context != nonempty && context != empty) {
+ throw new JSONException("Nesting problem");
+ }
+
+ stack.remove(stack.size() - 1);
+ if (context == nonempty) {
+ newline();
+ }
+ out.append(closeBracket);
+ return this;
+ }
+
+ /**
+ * Returns the value on the top of the stack.
+ */
+
+ private Scope peek() throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ return stack.get(stack.size() - 1);
+ }
+
+ /**
+ * Replace the value on the top of the stack with the given value.
+ */
+
+ private void replaceTop(Scope topOfStack) {
+ stack.set(stack.size() - 1, topOfStack);
+ }
+
+ /**
+ * Encodes {@code value}.
+ *
+ * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs}
+ * or {@link Double#isInfinite() infinities}.
+ * @return this stringer.
+ */
+ public JSONStringer value(Object value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+
+ if (value instanceof JSONArray) {
+ ((JSONArray) value).writeTo(this);
+ return this;
+
+ } else if (value instanceof JSONObject) {
+ ((JSONObject) value).writeTo(this);
+ return this;
+ }
+
+ beforeValue();
+
+ if (value == null
+ || value instanceof Boolean
+ || value == JSONObject.NULL) {
+ out.append(value);
+
+ } else if (value instanceof Number) {
+ out.append(JSONObject.numberToString((Number) value));
+
+ } else {
+ string(value.toString());
+ }
+
+ return this;
+ }
+
+ /**
+ * Encodes {@code value} to this stringer.
+ *
+ * @return this stringer.
+ */
+ public JSONStringer value(boolean value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ beforeValue();
+ out.append(value);
+ return this;
+ }
+
+ /**
+ * Encodes {@code value} to this stringer.
+ *
+ * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * @return this stringer.
+ */
+ public JSONStringer value(double value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ beforeValue();
+ out.append(JSONObject.numberToString(value));
+ return this;
+ }
+
+ /**
+ * Encodes {@code value} to this stringer.
+ *
+ * @return this stringer.
+ */
+ public JSONStringer value(long value) throws JSONException {
+ if (stack.isEmpty()) {
+ throw new JSONException("Nesting problem");
+ }
+ beforeValue();
+ out.append(value);
+ return this;
+ }
+
+
+ private void string(String value) {
+ out.append("\"");
+ for (int i = 0, length = value.length(); i < length; i++) {
+ char c = value.charAt(i);
+
+ /*
+ * From RFC 4627, "All Unicode characters may be placed within the
+ * quotation marks except for the characters that must be escaped:
+ * quotation mark, reverse solidus, and the control characters
+ * (U+0000 through U+001F)."
+ */
+ switch (c) {
+ case '"':
+ case '\\':
+ case '/':
+ out.append('\\').append(c);
+ break;
+
+ case '\t':
+ out.append("\\t");
+ break;
+
+ case '\b':
+ out.append("\\b");
+ break;
+
+ case '\n':
+ out.append("\\n");
+ break;
+
+ case '\r':
+ out.append("\\r");
+ break;
+
+ case '\f':
+ out.append("\\f");
+ break;
+
+ default:
+ if (c <= 0x1F) {
+ out.append(String.format("\\u%04x", (int) c));
+ } else {
+ out.append(c);
+ }
+ break;
+ }
+
+ }
+ out.append("\"");
+ }
+
+
+ private void newline() {
+ if (indent == null) {
+ return;
+ }
+
+ out.append("\n");
+ for (int i = 0; i < stack.size(); i++) {
+ out.append(indent);
+ }
+ }
+
+ /**
+ * Encodes the key (property name) to this stringer.
+ *
+ * @param name the name of the forthcoming value. May not be null.
+ * @return this stringer.
+ */
+ public JSONStringer key(String name) throws JSONException {
+ if (name == null) {
+ throw new JSONException("Names must be non-null");
+ }
+ beforeKey();
+ string(name);
+ return this;
+ }
+
+ /**
+ * Inserts any necessary separators and whitespace before a name. Also
+ * adjusts the stack to expect the key's value.
+ */
+
+ private void beforeKey() throws JSONException {
+ Scope context = peek();
+ if (context == Scope.NONEMPTY_OBJECT) { // first in object
+ out.append(',');
+ } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
+ throw new JSONException("Nesting problem");
+ }
+ newline();
+ replaceTop(Scope.DANGLING_KEY);
+ }
+
+ /**
+ * Inserts any necessary separators and whitespace before a literal value,
+ * inline array, or inline object. Also adjusts the stack to expect either a
+ * closing bracket or another element.
+ */
+
+ private void beforeValue() throws JSONException {
+ if (stack.isEmpty()) {
+ return;
+ }
+
+ Scope context = peek();
+ if (context == Scope.EMPTY_ARRAY) { // first in array
+ replaceTop(Scope.NONEMPTY_ARRAY);
+ newline();
+ } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
+ out.append(',');
+ newline();
+ } else if (context == Scope.DANGLING_KEY) { // value for key
+ out.append(indent == null ? ":" : ": ");
+ replaceTop(Scope.NONEMPTY_OBJECT);
+ } else if (context != Scope.NULL) {
+ throw new JSONException("Nesting problem");
+ }
+ }
+
+ /**
+ * Returns the encoded JSON string.
+ *
+ * If invoked with unterminated arrays or unclosed objects, this method's
+ * return value is undefined.
+ *
+ *
Warning: although it contradicts the general contract
+ * of {@link Object#toString}, this method returns null if the stringer
+ * contains no data.
+ */
+ @Override
+ public String toString() {
+ return out.length() == 0 ? null : out.toString();
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONTokener.java b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONTokener.java
new file mode 100644
index 0000000000000000000000000000000000000000..026a04f935595a7978c08b5cf980be341e71ba5a
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/java/org/json/JSONTokener.java
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * Parses a JSON (RFC 4627 )
+ * encoded string into the corresponding object. Most clients of
+ * this class will use only need the {@link #JSONTokener(String) constructor}
+ * and {@link #nextValue} method. Example usage:
+ * String json = "{"
+ * + " \"query\": \"Pizza\", "
+ * + " \"locations\": [ 94043, 90210 ] "
+ * + "}";
+ *
+ * JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
+ * String query = object.getString("query");
+ * JSONArray locations = object.getJSONArray("locations");
+ *
+ * For best interoperability and performance use JSON that complies with
+ * RFC 4627, such as that generated by {@link JSONStringer}. For legacy reasons
+ * this parser is lenient, so a successful parse does not indicate that the
+ * input string was valid JSON. All of the following syntax errors will be
+ * ignored:
+ *
+ * End of line comments starting with {@code //} or {@code #} and ending
+ * with a newline character.
+ * C-style comments starting with {@code /*} and ending with
+ * {@code *}{@code /}. Such comments may not be nested.
+ * Strings that are unquoted or {@code 'single quoted'}.
+ * Hexadecimal integers prefixed with {@code 0x} or {@code 0X}.
+ * Octal integers prefixed with {@code 0}.
+ * Array elements separated by {@code ;}.
+ * Unnecessary array separators. These are interpreted as if null was the
+ * omitted value.
+ * Key-value pairs separated by {@code =} or {@code =>}.
+ * Key-value pairs separated by {@code ;}.
+ *
+ *
+ * Each tokener may be used to parse a single JSON string. Instances of this
+ * class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See Effective Java
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
+ */
+public class JSONTokener {
+
+ /**
+ * The input JSON.
+ */
+
+ private final String in;
+
+ /**
+ * The index of the next character to be returned by {@link #next}. When
+ * the input is exhausted, this equals the input's length.
+ */
+
+ private int pos;
+
+ /**
+ * @param in JSON encoded string. Null is not permitted and will yield a
+ * tokener that throws {@code NullPointerExceptions} when methods are
+ * called.
+ */
+ public JSONTokener(String in) {
+ // consume an optional byte order mark (BOM) if it exists
+ if (in != null && in.startsWith("\ufeff")) {
+ in = in.substring(1);
+ }
+ this.in = in;
+ }
+
+ /**
+ * Returns the next value from the input.
+ *
+ * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+ * Integer, Long, Double or {@link JSONObject#NULL}.
+ * @throws JSONException if the input is malformed.
+ */
+ public Object nextValue() throws JSONException {
+ int c = nextCleanInternal();
+ switch (c) {
+ case -1:
+ throw syntaxError("End of input");
+
+ case '{':
+ return readObject();
+
+ case '[':
+ return readArray();
+
+ case '\'':
+ case '"':
+ return nextString((char) c);
+
+ default:
+ pos--;
+ return readLiteral();
+ }
+ }
+
+
+ private int nextCleanInternal() throws JSONException {
+ while (pos < in.length()) {
+ int c = in.charAt(pos++);
+ switch (c) {
+ case '\t':
+ case ' ':
+ case '\n':
+ case '\r':
+ continue;
+
+ case '/':
+ if (pos == in.length()) {
+ return c;
+ }
+
+ char peek = in.charAt(pos);
+ switch (peek) {
+ case '*':
+ // skip a /* c-style comment */
+ pos++;
+ int commentEnd = in.indexOf("*/", pos);
+ if (commentEnd == -1) {
+ throw syntaxError("Unterminated comment");
+ }
+ pos = commentEnd + 2;
+ continue;
+
+ case '/':
+ // skip a // end-of-line comment
+ pos++;
+ skipToEndOfLine();
+ continue;
+
+ default:
+ return c;
+ }
+
+ case '#':
+ /*
+ * Skip a # hash end-of-line comment. The JSON RFC doesn't
+ * specify this behavior, but it's required to parse
+ * existing documents. See http://b/2571423.
+ */
+ skipToEndOfLine();
+ continue;
+
+ default:
+ return c;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Advances the position until after the next newline character. If the line
+ * is terminated by "\r\n", the '\n' must be consumed as whitespace by the
+ * caller.
+ */
+
+ private void skipToEndOfLine() {
+ for (; pos < in.length(); pos++) {
+ char c = in.charAt(pos);
+ if (c == '\r' || c == '\n') {
+ pos++;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Returns the string up to but not including {@code quote}, unescaping any
+ * character escape sequences encountered along the way. The opening quote
+ * should have already been read. This consumes the closing quote, but does
+ * not include it in the returned string.
+ *
+ * @param quote either ' or ".
+ */
+ public String nextString(char quote) throws JSONException {
+ /*
+ * For strings that are free of escape sequences, we can just extract
+ * the result as a substring of the input. But if we encounter an escape
+ * sequence, we need to use a StringBuilder to compose the result.
+ */
+ StringBuilder builder = null;
+
+ /* the index of the first character not yet appended to the builder. */
+ int start = pos;
+
+ while (pos < in.length()) {
+ int c = in.charAt(pos++);
+ if (c == quote) {
+ if (builder == null) {
+ // a new string avoids leaking memory
+ return new String(in.substring(start, pos - 1));
+ } else {
+ builder.append(in, start, pos - 1);
+ return builder.toString();
+ }
+ }
+
+ if (c == '\\') {
+ if (pos == in.length()) {
+ throw syntaxError("Unterminated escape sequence");
+ }
+ if (builder == null) {
+ builder = new StringBuilder();
+ }
+ builder.append(in, start, pos - 1);
+ builder.append(readEscapeCharacter());
+ start = pos;
+ }
+ }
+
+ throw syntaxError("Unterminated string");
+ }
+
+ /**
+ * Unescapes the character identified by the character or characters that
+ * immediately follow a backslash. The backslash '\' should have already
+ * been read. This supports both unicode escapes "u000A" and two-character
+ * escapes "\n".
+ */
+
+ private char readEscapeCharacter() throws JSONException {
+ char escaped = in.charAt(pos++);
+ switch (escaped) {
+ case 'u':
+ if (pos + 4 > in.length()) {
+ throw syntaxError("Unterminated escape sequence");
+ }
+ String hex = in.substring(pos, pos + 4);
+ pos += 4;
+ try {
+ return (char) Integer.parseInt(hex, 16);
+ } catch (NumberFormatException nfe) {
+ throw syntaxError("Invalid escape sequence: " + hex);
+ }
+
+ case 't':
+ return '\t';
+
+ case 'b':
+ return '\b';
+
+ case 'n':
+ return '\n';
+
+ case 'r':
+ return '\r';
+
+ case 'f':
+ return '\f';
+
+ case '\'':
+ case '"':
+ case '\\':
+ default:
+ return escaped;
+ }
+ }
+
+ /**
+ * Reads a null, boolean, numeric or unquoted string literal value. Numeric
+ * values will be returned as an Integer, Long, or Double, in that order of
+ * preference.
+ */
+
+ private Object readLiteral() throws JSONException {
+ String literal = nextToInternal("{}[]/\\:,=;# \t\f");
+
+ if (literal.length() == 0) {
+ throw syntaxError("Expected literal value");
+ } else if ("null".equalsIgnoreCase(literal)) {
+ return JSONObject.NULL;
+ } else if ("true".equalsIgnoreCase(literal)) {
+ return Boolean.TRUE;
+ } else if ("false".equalsIgnoreCase(literal)) {
+ return Boolean.FALSE;
+ }
+
+ /* try to parse as an integral type... */
+ if (literal.indexOf('.') == -1) {
+ int base = 10;
+ String number = literal;
+ if (number.startsWith("0x") || number.startsWith("0X")) {
+ number = number.substring(2);
+ base = 16;
+ } else if (number.startsWith("0") && number.length() > 1) {
+ number = number.substring(1);
+ base = 8;
+ }
+ try {
+ long longValue = Long.parseLong(number, base);
+ if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
+ return (int) longValue;
+ } else {
+ return longValue;
+ }
+ } catch (NumberFormatException e) {
+ /*
+ * This only happens for integral numbers greater than
+ * Long.MAX_VALUE, numbers in exponential form (5e-10) and
+ * unquoted strings. Fall through to try floating point.
+ */
+ }
+ }
+
+ /* ...next try to parse as a floating point... */
+ try {
+ return Double.valueOf(literal);
+ } catch (NumberFormatException ignored) {
+ }
+
+ /* ... finally give up. We have an unquoted string */
+ return new String(literal); // a new string avoids leaking memory
+ }
+
+ /**
+ * Returns the string up to but not including any of the given characters or
+ * a newline character. This does not consume the excluded character.
+ */
+
+ private String nextToInternal(String excluded) {
+ int start = pos;
+ for (; pos < in.length(); pos++) {
+ char c = in.charAt(pos);
+ if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
+ return in.substring(start, pos);
+ }
+ }
+ return in.substring(start);
+ }
+
+ /**
+ * Reads a sequence of key/value pairs and the trailing closing brace '}' of
+ * an object. The opening brace '{' should have already been read.
+ */
+
+ private JSONObject readObject() throws JSONException {
+ JSONObject result = new JSONObject();
+
+ /* Peek to see if this is the empty object. */
+ int first = nextCleanInternal();
+ if (first == '}') {
+ return result;
+ } else if (first != -1) {
+ pos--;
+ }
+
+ while (true) {
+ Object name = nextValue();
+ if (!(name instanceof String)) {
+ if (name == null) {
+ throw syntaxError("Names cannot be null");
+ } else {
+ throw syntaxError("Names must be strings, but " + name
+ + " is of type " + name.getClass().getName());
+ }
+ }
+
+ /*
+ * Expect the name/value separator to be either a colon ':', an
+ * equals sign '=', or an arrow "=>". The last two are bogus but we
+ * include them because that's what the original implementation did.
+ */
+ int separator = nextCleanInternal();
+ if (separator != ':' && separator != '=') {
+ throw syntaxError("Expected ':' after " + name);
+ }
+ if (pos < in.length() && in.charAt(pos) == '>') {
+ pos++;
+ }
+
+ result.put((String) name, nextValue());
+
+ switch (nextCleanInternal()) {
+ case '}':
+ return result;
+ case ';':
+ case ',':
+ continue;
+ default:
+ throw syntaxError("Unterminated object");
+ }
+ }
+ }
+
+ /**
+ * Reads a sequence of values and the trailing closing brace ']' of an
+ * array. The opening brace '[' should have already been read. Note that
+ * "[]" yields an empty array, but "[,]" returns a two-element array
+ * equivalent to "[null,null]".
+ */
+
+ private JSONArray readArray() throws JSONException {
+ JSONArray result = new JSONArray();
+
+ /* to cover input that ends with ",]". */
+ boolean hasTrailingSeparator = false;
+
+ while (true) {
+ switch (nextCleanInternal()) {
+ case -1:
+ throw syntaxError("Unterminated array");
+ case ']':
+ if (hasTrailingSeparator) {
+ result.put(null);
+ }
+ return result;
+ case ',':
+ case ';':
+ /* A separator without a value first means "null". */
+ result.put(null);
+ hasTrailingSeparator = true;
+ continue;
+ default:
+ pos--;
+ }
+
+ result.put(nextValue());
+
+ switch (nextCleanInternal()) {
+ case ']':
+ return result;
+ case ',':
+ case ';':
+ hasTrailingSeparator = true;
+ continue;
+ default:
+ throw syntaxError("Unterminated array");
+ }
+ }
+ }
+
+ /**
+ * Returns an exception containing the given message plus the current
+ * position and the entire input string.
+ */
+ public JSONException syntaxError(String message) {
+ return new JSONException(message + this);
+ }
+
+ /**
+ * Returns the current position and the entire input string.
+ */
+ @Override
+ public String toString() {
+ // consistent with the original implementation
+ return " at character " + pos + " of " + in;
+ }
+
+ /*
+ * Legacy APIs.
+ *
+ * None of the methods below are on the critical path of parsing JSON
+ * documents. They exist only because they were exposed by the original
+ * implementation and may be used by some clients.
+ */
+
+ /**
+ * Returns true until the input has been exhausted.
+ */
+ public boolean more() {
+ return pos < in.length();
+ }
+
+ /**
+ * Returns the next available character, or the null character '\0' if all
+ * input has been exhausted. The return value of this method is ambiguous
+ * for JSON strings that contain the character '\0'.
+ */
+ public char next() {
+ return pos < in.length() ? in.charAt(pos++) : '\0';
+ }
+
+ /**
+ * Returns the next available character if it equals {@code c}. Otherwise an
+ * exception is thrown.
+ */
+ public char next(char c) throws JSONException {
+ char result = next();
+ if (result != c) {
+ throw syntaxError("Expected " + c + " but was " + result);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the next character that is not whitespace and does not belong to
+ * a comment. If the input is exhausted before such a character can be
+ * found, the null character '\0' is returned. The return value of this
+ * method is ambiguous for JSON strings that contain the character '\0'.
+ */
+ public char nextClean() throws JSONException {
+ int nextCleanInt = nextCleanInternal();
+ return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
+ }
+
+ /**
+ * Returns the next {@code length} characters of the input.
+ *
+ *
The returned string shares its backing character array with this
+ * tokener's input string. If a reference to the returned string may be held
+ * indefinitely, you should use {@code new String(result)} to copy it first
+ * to avoid memory leaks.
+ *
+ * @throws JSONException if the remaining input is not long enough to
+ * satisfy this request.
+ */
+ public String next(int length) throws JSONException {
+ if (pos + length > in.length()) {
+ throw syntaxError(length + " is out of bounds");
+ }
+ String result = in.substring(pos, pos + length);
+ pos += length;
+ return result;
+ }
+
+ /**
+ * Returns the {@link String#trim trimmed} string holding the characters up
+ * to but not including the first of:
+ *
+ * any character in {@code excluded}
+ * a newline character '\n'
+ * a carriage return '\r'
+ *
+ *
+ * The returned string shares its backing character array with this
+ * tokener's input string. If a reference to the returned string may be held
+ * indefinitely, you should use {@code new String(result)} to copy it first
+ * to avoid memory leaks.
+ *
+ * @return a possibly-empty string
+ */
+ public String nextTo(String excluded) {
+ if (excluded == null) {
+ throw new NullPointerException("excluded == null");
+ }
+ return nextToInternal(excluded).trim();
+ }
+
+ /**
+ * Equivalent to {@code nextTo(String.valueOf(excluded))}.
+ */
+ public String nextTo(char excluded) {
+ return nextToInternal(String.valueOf(excluded)).trim();
+ }
+
+ /**
+ * Advances past all input up to and including the next occurrence of
+ * {@code thru}. If the remaining input doesn't contain {@code thru}, the
+ * input is exhausted.
+ */
+ public void skipPast(String thru) {
+ int thruStart = in.indexOf(thru, pos);
+ pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
+ }
+
+ /**
+ * Advances past all input up to but not including the next occurrence of
+ * {@code to}. If the remaining input doesn't contain {@code to}, the input
+ * is unchanged.
+ */
+ public char skipTo(char to) {
+ int index = in.indexOf(to, pos);
+ if (index != -1) {
+ pos = index;
+ return to;
+ } else {
+ return '\0';
+ }
+ }
+
+ /**
+ * Unreads the most recent character of input. If no input characters have
+ * been read, the input is unchanged.
+ */
+ public void back() {
+ if (--pos == -1) {
+ pos = 0;
+ }
+ }
+
+ /**
+ * Returns the integer [0..15] value for the given hex character, or -1
+ * for non-hex input.
+ *
+ * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other
+ * character will yield a -1 result.
+ */
+ public static int dehexchar(char hex) {
+ if (hex >= '0' && hex <= '9') {
+ return hex - '0';
+ } else if (hex >= 'A' && hex <= 'F') {
+ return hex - 'A' + 10;
+ } else if (hex >= 'a' && hex <= 'f') {
+ return hex - 'a' + 10;
+ } else {
+ return -1;
+ }
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/resources/base/element/string.json b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2c8ad3d11f236e131865b498f009f25a742e7c59
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/Logger_harmony/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Logger_harmony"
+ }
+ ]
+}
diff --git a/002.Logger_OpenHarmony-master/code/build.gradle b/002.Logger_OpenHarmony-master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..7f82a87bd3fe9820f6c52998dbd984648a912678
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/build.gradle
@@ -0,0 +1,38 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ classpath 'com.huawei.ohos:hap:2.4.0.1'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/entry/.gitignore b/002.Logger_OpenHarmony-master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/002.Logger_OpenHarmony-master/code/entry/build.gradle b/002.Logger_OpenHarmony-master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4c64d77add9ff66b3b0720d839e01594eb913748
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/build.gradle
@@ -0,0 +1,16 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ implementation project(":Logger_harmony")
+ implementation 'org.jetbrains:annotations:15.0'
+
+}
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/config.json b/002.Logger_OpenHarmony-master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..f04813e5a19ddd360cae1d139b05880f1b7eee83
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/main/config.json
@@ -0,0 +1,56 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.myapplication",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone",
+ "tv"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.myapplication.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:label_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.READ_USER_STORAGE"
+
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java b/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..813ed4e7594dc5d3545f66e7f9ac76aab74be555
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.myapplication;
+
+import com.example.myapplication.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java b/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..160bab2d67eba94b79d7e5f76b1c0d98208e0c1b
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java
@@ -0,0 +1,20 @@
+package com.example.myapplication;
+
+import com.example.logger_harmony.BuildConfig;
+import com.example.logger_harmony.HarmonyOsLogAdapter;
+import com.example.logger_harmony.Logger;
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+
+ Logger.addLogAdapter(new HarmonyOsLogAdapter() {
+ @Override
+ public boolean isLoggable(int priority, @org.jetbrains.annotations.Nullable String tag) {
+ return BuildConfig.DEBUG;
+ }
+ });
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java b/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd829a0d49c80cba5723050f35358517815e9106
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java
@@ -0,0 +1,79 @@
+package com.example.myapplication.slice;
+
+import com.example.logger_harmony.*;
+import com.example.myapplication.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class MainAbilitySlice extends AbilitySlice {
+ Context context;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ context = this;
+ Text text = (Text) findComponentById(ResourceTable.Id_text_helloworld);
+
+ text.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+
+ try {
+ Logger.i("需要打印的日志信息");
+// Logger.i("需要打印的日志信息");
+// Logger.t("tag标签").i("需要打印的日志信息");
+// Logger.json("{\"key\": 3, \"value\": something}");
+
+// List list = new ArrayList<>();
+// for (int i = 0; i < 5; i++) {
+// list.add(i);
+// }
+// Logger.i(Arrays.asList(list));
+
+// FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
+// .showThreadInfo(false) // (Optional) Whether to show thread info or not. Default true
+// .methodCount(0) // (Optional) How many method line to show. Default 2
+// .methodOffset(7) // (Optional) Hides internal method calls up to offset. Default 5
+// .logStrategy(new LogcatLogStrategy()) // (Optional) Changes the log strategy to print out. Default LogCat
+// .tag("My custom tag") // (Optional) Global tag for every log. Default PRETTY_LOGGER
+// .build();
+//
+// Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy));
+// Logger.addLogAdapter(new DiskLogAdapter(context));
+
+
+// Logger.i(Arrays.asList(list));
+
+// Map map = new HashMap<>();
+// map.put("key", "value");
+// map.put("key1", "value2");
+
+// Logger.d(map);
+// HiLog.info(label,"info");
+// HiLog.error(label,"error");
+// HiLog.fatal(label,"fatal");
+// HiLog.warn(label,"warn");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..915bc65a5cd104e1a936085e2c66e0a1a1b4a2d6
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "label_name",
+ "value": "MyApplication"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..264aab6dabe3cedb809d47cfa3b0dfc1a3d5b56a
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/002.Logger_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/002.Logger_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java b/002.Logger_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..160d520624e9b69a368ef2d9903f914e1be01474
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.myapplication;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/002.Logger_OpenHarmony-master/code/gradle.properties b/002.Logger_OpenHarmony-master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/002.Logger_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar b/002.Logger_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/002.Logger_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/002.Logger_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties b/002.Logger_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/002.Logger_OpenHarmony-master/code/gradlew b/002.Logger_OpenHarmony-master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/002.Logger_OpenHarmony-master/code/gradlew.bat b/002.Logger_OpenHarmony-master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/002.Logger_OpenHarmony-master/code/settings.gradle b/002.Logger_OpenHarmony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..82c96cd30ac07fc52ca421a9be7b554a02cc44f9
--- /dev/null
+++ b/002.Logger_OpenHarmony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':Logger_harmony'
diff --git "a/002.Logger_OpenHarmony-master/doc/002\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204Logger\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/002.Logger_OpenHarmony-master/doc/002\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204Logger\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..ad8e8651274c15a0717a0548c5f16757214e237f
Binary files /dev/null and "b/002.Logger_OpenHarmony-master/doc/002\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204Logger\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/003.Active_OpenHarmony-master/code/.gitignore b/003.Active_OpenHarmony-master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/003.Active_OpenHarmony-master/code/.idea/.gitignore b/003.Active_OpenHarmony-master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/003.Active_OpenHarmony-master/code/.idea/compiler.xml b/003.Active_OpenHarmony-master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/.idea/gradle.xml b/003.Active_OpenHarmony-master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f0b6549e50dad37933cc5898dc35391764feb555
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/.idea/gradle.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/.idea/jarRepositories.xml b/003.Active_OpenHarmony-master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/.idea/misc.xml b/003.Active_OpenHarmony-master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/build.gradle b/003.Active_OpenHarmony-master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..becc5f7f724a94c358eb4619c7c42c80aadbd2fa
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.2.5'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/003.Active_OpenHarmony-master/code/entry/.gitignore b/003.Active_OpenHarmony-master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/003.Active_OpenHarmony-master/code/entry/build.gradle b/003.Active_OpenHarmony-master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..eb0e5c839fcabef970d330af3644e9012304154f
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+ compileOptions{
+ annotationEnabled true
+ }
+
+}
+
+dependencies {
+
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ compile files(
+ "./libs/javapoet_java.jar",
+ "./libs/orm_annotations_java.jar",
+ "./libs/orm_annotations_processor_java.jar")
+ annotationProcessor files(
+ "./libs/javapoet_java.jar",
+ "./libs/orm_annotations_java.jar",
+ "./libs/orm_annotations_processor_java.jar")
+}
diff --git a/003.Active_OpenHarmony-master/code/entry/libs/javapoet_java.jar b/003.Active_OpenHarmony-master/code/entry/libs/javapoet_java.jar
new file mode 100644
index 0000000000000000000000000000000000000000..00c9f224929bc94ae190331df3bead74bc223a62
Binary files /dev/null and b/003.Active_OpenHarmony-master/code/entry/libs/javapoet_java.jar differ
diff --git a/003.Active_OpenHarmony-master/code/entry/libs/orm_annotations_java.jar b/003.Active_OpenHarmony-master/code/entry/libs/orm_annotations_java.jar
new file mode 100644
index 0000000000000000000000000000000000000000..77f4815a5deba557bf6aa9efe5838bdf8c570800
Binary files /dev/null and b/003.Active_OpenHarmony-master/code/entry/libs/orm_annotations_java.jar differ
diff --git a/003.Active_OpenHarmony-master/code/entry/libs/orm_annotations_processor_java.jar b/003.Active_OpenHarmony-master/code/entry/libs/orm_annotations_processor_java.jar
new file mode 100644
index 0000000000000000000000000000000000000000..bbfd41bbb81b6f26827a4b88ea9b4b8f929be67a
Binary files /dev/null and b/003.Active_OpenHarmony-master/code/entry/libs/orm_annotations_processor_java.jar differ
diff --git a/003.Active_OpenHarmony-master/code/entry/libs/sqlitelibrary-debug.har b/003.Active_OpenHarmony-master/code/entry/libs/sqlitelibrary-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..3ee22eb9fdf1718a3451ea1e699e1beba905f210
Binary files /dev/null and b/003.Active_OpenHarmony-master/code/entry/libs/sqlitelibrary-debug.har differ
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/config.json b/003.Active_OpenHarmony-master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..099e70eab45d713710ff06f869eb53da5e892c52
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 3,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.myapplication",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.myapplication.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/BookStore.java b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/BookStore.java
new file mode 100644
index 0000000000000000000000000000000000000000..7cc48315fd4953d884abfc46a4acd54907415df5
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/BookStore.java
@@ -0,0 +1,8 @@
+package com.example.myapplication;
+
+import ohos.data.orm.OrmDatabase;
+import ohos.data.orm.annotation.Database;
+
+@Database(entities = {User.class}, version = 1)
+public abstract class BookStore extends OrmDatabase {
+}
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..813ed4e7594dc5d3545f66e7f9ac76aab74be555
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.myapplication;
+
+import com.example.myapplication.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..33915e2cc691b0fa169fd0a13e2262ac3925bafd
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.myapplication;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/User.java b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe727d20f95931ccac600ddf313f7c499161c600
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/User.java
@@ -0,0 +1,79 @@
+package com.example.myapplication;
+
+import ohos.data.orm.OrmObject;
+import ohos.data.orm.annotation.Entity;
+import ohos.data.orm.annotation.Index;
+import ohos.data.orm.annotation.PrimaryKey;
+
+
+@Entity(tableName = "user", ignoredColumns = {"ignoreColumn1", "ignoreColumn2"},
+ indices = {@Index(value = {"firstName", "lastName"}, name = "name_index", unique = true)})
+public class User extends OrmObject {
+ // 此处将userId设为了自增的主键。注意只有在数据类型为包装类型时,自增主键才能生效。
+ @PrimaryKey(autoGenerate = true)
+ private Integer userId;
+ private String firstName;
+ private String lastName;
+ private int age;
+ private double balance;
+ private int ignoreColumn1;
+ private int ignoreColumn2;
+
+ // 开发者自行添加字段的getter和setter 方法。
+
+ public Integer getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Integer userId) {
+ this.userId = userId;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public double getBalance() {
+ return balance;
+ }
+
+ public void setBalance(double balance) {
+ this.balance = balance;
+ }
+
+ public int getIgnoreColumn1() {
+ return ignoreColumn1;
+ }
+
+ public void setIgnoreColumn1(int ignoreColumn1) {
+ this.ignoreColumn1 = ignoreColumn1;
+ }
+
+ public int getIgnoreColumn2() {
+ return ignoreColumn2;
+ }
+
+ public void setIgnoreColumn2(int ignoreColumn2) {
+ this.ignoreColumn2 = ignoreColumn2;
+ }
+}
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..c12ce5030e4c65102b35e8525c959fdc12b944dd
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java
@@ -0,0 +1,119 @@
+package com.example.myapplication.slice;
+
+import com.example.myapplication.BookStore;
+import com.example.myapplication.ResourceTable;
+import com.example.myapplication.User;
+import com.example.sqlitelibrary.DBManage;
+import com.example.sqlitelibrary.DBOrmContext;
+import com.example.sqlitelibrary.utils.Log;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.data.DatabaseHelper;
+import ohos.data.orm.OrmContext;
+import ohos.data.orm.OrmPredicates;
+import ohos.data.rdb.RdbStore;
+import ohos.data.rdb.ValuesBucket;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
+
+ private DatabaseHelper helper;
+ private RdbStore store;
+ private OrmContext context;
+ private Text textResult;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ helper = new DatabaseHelper(this);
+ DBManage dbManger = new DBManage("user.db","user");
+ context = dbManger.getConnectionContext(helper, BookStore.class);
+// DBManage dbManger = new DBManage("user.db");
+// store = dbManger.getConnectionStore(helper,"user");
+ Button btnInsert = (Button) findComponentById(ResourceTable.Id_btn_insert);
+ Button btnQuery = (Button) findComponentById(ResourceTable.Id_btn_query);
+ Button btnDelete = (Button) findComponentById(ResourceTable.Id_btn_delete);
+ Button btnUpdate = (Button) findComponentById(ResourceTable.Id_btn_update);
+ textResult = (Text) findComponentById(ResourceTable.Id_text);
+ btnInsert.setClickedListener(this::onClick);
+ btnQuery.setClickedListener(this::onClick);
+ btnDelete.setClickedListener(this::onClick);
+ btnUpdate.setClickedListener(this::onClick);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+ @Override
+ public void onClick(Component component) {
+// RdbStoreManage rdbStoreMange = new RdbStoreManage();
+// ValuesBucket values = new ValuesBucket();
+// values.putInteger("id", 1);
+// values.putString("name", "zhangsan");
+// values.putInteger("age", 18);
+// values.putDouble("salary", 100.5);
+// values.putByteArray("blobType", new byte[] {1, 2, 3});
+// rdbStoreMange.setSql(store, "insert into user values(zhangsan, 18, 100.5, byte[1,2,3])");
+// long id = rdbStoreMange.insert(store,"user", values);
+// System.out.println(id);
+
+
+ DBOrmContext dbOrmContext = new DBOrmContext();
+ switch (component.getId()) {
+ case ResourceTable.Id_btn_insert: //插入数据
+ //第一次使用user对应的表的时候,如果有这张表就直接使用,没有就创建表
+ User user = new User();
+ user.setFirstName("Zhang");
+ user.setLastName("San");
+ user.setAge(29);
+ user.setBalance(100.51);
+ boolean b = dbOrmContext.insert(context, user);
+ System.out.println("插入成功 "+b);
+ textResult.setText(user.getFirstName()+" "+user.getLastName()+" "+user.getAge()+" "+user.getBalance());
+ break;
+ case ResourceTable.Id_btn_query: //条件查询
+ List users = new ArrayList<>();
+ OrmPredicates query = context.where(User.class).equalTo("lastName", "San");
+ users = dbOrmContext.query(context, query);
+ System.out.println("查询 "+users.size());
+ for (User user1 : users) {
+ textResult.setText(user1.getFirstName()+" "+user1.getLastName()+" "+user1.getAge()+" "+user1.getBalance() +"\n");
+ }
+
+ break;
+ case ResourceTable.Id_btn_delete: //条件删除
+ OrmPredicates delete = context.where(User.class).equalTo("lastName", "San");
+ int delete1 = dbOrmContext.delete(context, delete);
+ System.out.println("删除成功 "+delete1);
+ textResult.setText("删除成功");
+ break;
+ case ResourceTable.Id_btn_update: //条件更新
+ ValuesBucket valuesBucket = new ValuesBucket();
+ valuesBucket.putInteger("age", 31);
+ valuesBucket.putString("firstName", "Zhang");
+ valuesBucket.putString("lastName", "San");
+ valuesBucket.putDouble("balance", 300.51);
+ OrmPredicates update = context.where(User.class).equalTo("userId", 1);
+ int update1 = dbOrmContext.update(context, valuesBucket, update);
+ System.out.println("更新成功 "+update1);
+ textResult.setText(valuesBucket.getString("firstName")+" "+valuesBucket.getString("lastName")+" "+valuesBucket.getInteger("age")+" "+valuesBucket.getDouble("balance"));
+ break;
+ }
+
+ dbOrmContext.flush(context);
+
+ }
+}
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..929389e237a263eebc2e130fc06c892bd59404ef
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "dataability_description",
+ "value": "hap sample empty provider"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cc455eed2c426aa1f01aed388cce957c3a3e9f94
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/003.Active_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/003.Active_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java b/003.Active_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..160d520624e9b69a368ef2d9903f914e1be01474
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.myapplication;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/003.Active_OpenHarmony-master/code/gradle.properties b/003.Active_OpenHarmony-master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/003.Active_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar b/003.Active_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/003.Active_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/003.Active_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties b/003.Active_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/003.Active_OpenHarmony-master/code/gradlew b/003.Active_OpenHarmony-master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/003.Active_OpenHarmony-master/code/gradlew.bat b/003.Active_OpenHarmony-master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/003.Active_OpenHarmony-master/code/settings.gradle b/003.Active_OpenHarmony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07
--- /dev/null
+++ b/003.Active_OpenHarmony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry'
diff --git "a/003.Active_OpenHarmony-master/doc/003.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204ActiveOhos_sqllite\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/003.Active_OpenHarmony-master/doc/003.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204ActiveOhos_sqllite\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..57a1c73a6ea66f53b70e0ff0f445c99e7415909b
Binary files /dev/null and "b/003.Active_OpenHarmony-master/doc/003.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204ActiveOhos_sqllite\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/004.Compressor_OpenHamrony-master/code/.gitignore b/004.Compressor_OpenHamrony-master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/004.Compressor_OpenHamrony-master/code/.idea/.gitignore b/004.Compressor_OpenHamrony-master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/004.Compressor_OpenHamrony-master/code/.idea/compiler.xml b/004.Compressor_OpenHamrony-master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/.idea/gradle.xml b/004.Compressor_OpenHamrony-master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..53dfa3d3fdf05caed9bcf4fec48fbe5532df00d1
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.idea/gradle.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/.idea/jarRepositories.xml b/004.Compressor_OpenHamrony-master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/.idea/misc.xml b/004.Compressor_OpenHamrony-master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..58918f50335428f2efb3af4d621f9f405ed659d4
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/.idea/previewer/phone/phoneSettingConfig_-1921170013.json b/004.Compressor_OpenHamrony-master/code/.idea/previewer/phone/phoneSettingConfig_-1921170013.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.idea/previewer/phone/phoneSettingConfig_-1921170013.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/.idea/previewer/previewConfig.json b/004.Compressor_OpenHamrony-master/code/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..b156b365087c195a0fc696d8a2aa9c4bc62717a4
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/.idea/previewer/previewConfig.json
@@ -0,0 +1,9 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "C:\\Users\\issuser\\AppData\\Roaming\\WeLink\\appdata\\IM\\leiwang_825@isoftstone\\ReceiveFiles\\haros\\Compressor_Harmony-master\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/README.md b/004.Compressor_OpenHamrony-master/code/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3a5d531e5ad52c00d5eecc713a296b25e76c800d
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/README.md
@@ -0,0 +1 @@
+# Compressor_Harmony
diff --git a/004.Compressor_OpenHamrony-master/code/build.gradle b/004.Compressor_OpenHamrony-master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0f37d1b371f1632aaf2af4a2814463596cc0ddf0
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.2.5'
+ classpath 'com.huawei.ohos:decctest:1.0.0.6'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/004.Compressor_OpenHamrony-master/code/compress-debug.har b/004.Compressor_OpenHamrony-master/code/compress-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..1c583664524ab8a73c7e19830d6cf41f0b26416a
Binary files /dev/null and b/004.Compressor_OpenHamrony-master/code/compress-debug.har differ
diff --git a/004.Compressor_OpenHamrony-master/code/compress/.gitignore b/004.Compressor_OpenHamrony-master/code/compress/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/compress/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/004.Compressor_OpenHamrony-master/code/compress/build.gradle b/004.Compressor_OpenHamrony-master/code/compress/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/compress/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/004.Compressor_OpenHamrony-master/code/compress/src/main/config.json b/004.Compressor_OpenHamrony-master/code/compress/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..88c5a291c4e5ee50f7272592f36fede3fe3bbaae
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/compress/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.app",
+ "vendor": "soft",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.soft.stone.compress",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "compress",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/compress/src/main/java/com/soft/stone/compress/Compressor.java b/004.Compressor_OpenHamrony-master/code/compress/src/main/java/com/soft/stone/compress/Compressor.java
new file mode 100644
index 0000000000000000000000000000000000000000..4b8cc61d5f330cef926cf6ceb69408edc6ff9de4
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/compress/src/main/java/com/soft/stone/compress/Compressor.java
@@ -0,0 +1,87 @@
+package com.soft.stone.compress;
+
+import ohos.app.Context;
+import ohos.media.image.ImagePacker;
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+import ohos.media.image.common.Size;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class Compressor {
+
+ private Compressor() {}
+
+ /**
+ * 将图片转换成像素
+ *
+ * @param file 文件目录
+ * @return 像素
+ */
+ public static PixelMap decode(File file) {
+ ImageSource imageSource = ImageSource.create(file, null);
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.sampleSize = ImageSource.DecodingOptions.DEFAULT_SAMPLE_SIZE;
+ return imageSource.createPixelmap(decodingOpts);
+ }
+
+ /**
+ * 默认压缩
+ *
+ * @param context 上下文
+ * @param file 临时文件
+ * @return 临时文件
+ * @throws IOException IO异常
+ */
+ public static File defaultCompress(Context context, File file) throws IOException {
+ File tmpFile = copyToCache(context, file);
+ PixelMap pixelMap = decode(tmpFile, 612, 816);
+ refreshTmpFile(pixelMap, tmpFile, 80);
+ return tmpFile;
+ }
+
+ /**
+ * 自定义压缩
+ *
+ * @param context 上下文
+ * @param file 文件目录
+ * @param width 需要显示的宽度
+ * @param height 需要显示的高度
+ * @param quality 图片压缩质量
+ * @return 文件目录
+ * @throws IOException IO异常
+ */
+ public static File customCompress(Context context, File file, int width, int height, int quality) throws IOException {
+ File tmpFile = copyToCache(context, file);
+ PixelMap pixelMap = decode(tmpFile, width, height);
+ refreshTmpFile(pixelMap, tmpFile, quality);
+ return tmpFile;
+ }
+
+ private static File copyToCache(Context context, File imageFile) throws IOException {
+ PixelMap pixelMap = decode(imageFile);
+ String cachePath = context.getCacheDir() + File.separator + imageFile.getName();
+ File cacheFile = new File(cachePath);
+ int quality = 100; // 压缩质量
+ refreshTmpFile(pixelMap, cacheFile, quality);
+ return cacheFile;
+ }
+
+ private static void refreshTmpFile(PixelMap pixelMap, File file, int quality) throws IOException {
+ ImagePacker imagePacker = ImagePacker.create();
+ ImagePacker.PackingOptions options = new ImagePacker.PackingOptions();
+ options.quality = quality;
+ imagePacker.initializePacking(new FileOutputStream(file), options);
+ imagePacker.addImage(pixelMap);
+ imagePacker.finalizePacking();
+ }
+
+ private static PixelMap decode(File file, int width, int height) {
+ ImageSource imageSource = ImageSource.create(file, null);
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.desiredSize = new Size(width, height);
+ return imageSource.createPixelmap(decodingOpts);
+ }
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/compress/src/main/resources/base/element/string.json b/004.Compressor_OpenHamrony-master/code/compress/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..d0aa32ac861dc684eba146286301d7a7830b661d
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/compress/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Compress"
+ }
+ ]
+}
diff --git a/004.Compressor_OpenHamrony-master/code/entry/.gitignore b/004.Compressor_OpenHamrony-master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/004.Compressor_OpenHamrony-master/code/entry/build.gradle b/004.Compressor_OpenHamrony-master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..9d4c9e4967e54fe3e97ad7e4443900a947addd57
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ compile project(path: ':compress')
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/config.json b/004.Compressor_OpenHamrony-master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..4b1356a75fa02f181595432be365674bf5e90089
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/config.json
@@ -0,0 +1,56 @@
+{
+ "app": {
+ "bundleName": "com.example.app",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.app",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.WRITE_USER_STORAGE"
+ },
+ {
+ "name": "ohos.permission.READ_USER_STORAGE"
+ }
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.app.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "App",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/MainAbility.java b/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..388fa484ccd655db29568d0216c21ab66b5442dc
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.app;
+
+import com.example.app.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/MyApplication.java b/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..72495b99b09b536bd5510419c2a15cea5d608b83
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.app;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/slice/MainAbilitySlice.java b/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ec886297eb7d2d6590cef6b5d31c2119def9714
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/java/com/example/app/slice/MainAbilitySlice.java
@@ -0,0 +1,133 @@
+package com.example.app.slice;
+
+import com.example.app.ResourceTable;
+import com.soft.stone.compress.Compressor;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.ability.DataAbilityHelper;
+import ohos.aafwk.ability.DataAbilityRemoteException;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.components.Text;
+import ohos.agp.window.dialog.ToastDialog;
+import ohos.data.resultset.ResultSet;
+import ohos.global.resource.NotExistException;
+import ohos.global.resource.Resource;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.ImagePacker;
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+import ohos.media.photokit.metadata.AVStorage;
+import ohos.utils.net.Uri;
+
+import java.io.*;
+import java.util.UUID;
+
+public class MainAbilitySlice extends AbilitySlice {
+ private static final HiLogLabel LOG_LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "APP");
+
+ private String tmpName = null;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ // 请求文件的读取权限
+ String[] permissions = {"ohos.permission.READ_USER_STORAGE"};
+ requestPermissionsFromUser(permissions, 0);
+
+ // 获取压缩按钮并绑定事件
+ Button button = (Button) findComponentById(ResourceTable.Id_button);
+ if (button != null) {
+ // 为按钮设置点击回调
+ button.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ try {
+
+ // 手机得存储图片
+ File file = new File(System.getProperty("java.io.tmpdir") + File.separator + tmpName);
+ HiLog.error(LOG_LABEL, "old size..." + file.length() + " ...b");
+
+ // 默认压缩
+ // File newFile = Compressor.defaultCompress(file);
+
+ // 自定义压缩
+ File newFile = Compressor.customCompress(getContext(), file, 500, 1000, 60);
+
+ Text text = (Text) findComponentById(ResourceTable.Id_text);
+ text.setText("size: " + newFile.length() + " b");
+ HiLog.error(LOG_LABEL, "new size..." + newFile.length() + " ...b");
+ PixelMap newPixelMap = Compressor.decode(newFile);
+ Image image = (Image) findComponentById(ResourceTable.Id_image1);
+ image.setPixelMap(newPixelMap);
+
+
+ HiLog.error(LOG_LABEL, "file为空,请检查手机中是否有图片");
+
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ // 获取选择图片按钮并绑定事件
+ Button chooseButton = (Button) findComponentById(ResourceTable.Id_choose_button);
+ if (chooseButton != null) {
+ // 为按钮设置点击回调
+ chooseButton.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ DataAbilityHelper helper = DataAbilityHelper.creator(getContext());
+ try {
+ ResultSet resultSet = helper.query(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, null, null);
+ while (resultSet != null && resultSet.goToNextRow()) {
+ // 互殴媒体库的图片
+ int id = resultSet.getInt(resultSet.getColumnIndexForName(AVStorage.Images.Media.ID));
+ HiLog.error(LOG_LABEL, "id:..." + id + " ...");
+ Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, "" + id);
+ // 根据图片的uri打开文件并保存到临时目录中
+ FileDescriptor fileDescriptor = helper.openFile(uri, "r");
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.sampleSize = ImageSource.DecodingOptions.DEFAULT_SAMPLE_SIZE;
+ ImageSource imageSource = ImageSource.create(fileDescriptor, null);
+ PixelMap pixelMap = imageSource.createThumbnailPixelmap(decodingOpts, true);
+ ImagePacker imagePacker = ImagePacker.create();
+ tmpName = UUID.randomUUID().toString();
+ File file = new File(System.getProperty("java.io.tmpdir") + File.separator + tmpName);
+ FileOutputStream outputStream = new FileOutputStream(file);
+ ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
+ packingOptions.quality = 100;
+ boolean result = imagePacker.initializePacking(outputStream, packingOptions);
+ result = imagePacker.addImage(pixelMap);
+ long dataSize = imagePacker.finalizePacking();
+ // 显示图片和图片大小
+ Text text = (Text) findComponentById(ResourceTable.Id_text);
+ text.setText("size: " + file.length() + " b");
+ Image image = (Image) findComponentById(ResourceTable.Id_image1);
+ image.setPixelMap(pixelMap);
+ }
+ } catch (DataAbilityRemoteException | FileNotFoundException e) {
+ HiLog.error(LOG_LABEL, "exception:..." + e.getMessage());
+
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/element/string.json b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..60bf6758c1587350fc47480a4f6ae92b562ebe1b
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "App"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/graphic/background_button.xml b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/graphic/background_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..668c5c813c4e3cfe99445bcf4bddf1ec5e218235
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/graphic/background_button.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/layout/ability_main.xml b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..921584ad8fa8282e8725eb9b32f32d134c62e678
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/dog1.PNG b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/dog1.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..e81019c37dc236e27a24912805128ad3a6d40579
Binary files /dev/null and b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/dog1.PNG differ
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/dog2.PNG b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/dog2.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..1f9b6a77fb908415500b917810902578b9cc153d
Binary files /dev/null and b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/dog2.PNG differ
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/icon.png b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/004.Compressor_OpenHamrony-master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/004.Compressor_OpenHamrony-master/code/entry/src/test/java/com/example/app/ExampleTest.java b/004.Compressor_OpenHamrony-master/code/entry/src/test/java/com/example/app/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..56644cd0764679dab39aa701d3a9b2bad4f7166f
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/entry/src/test/java/com/example/app/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.app;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/004.Compressor_OpenHamrony-master/code/gradle.properties b/004.Compressor_OpenHamrony-master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/004.Compressor_OpenHamrony-master/code/gradle/wrapper/gradle-wrapper.jar b/004.Compressor_OpenHamrony-master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/004.Compressor_OpenHamrony-master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/004.Compressor_OpenHamrony-master/code/gradle/wrapper/gradle-wrapper.properties b/004.Compressor_OpenHamrony-master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/004.Compressor_OpenHamrony-master/code/gradlew b/004.Compressor_OpenHamrony-master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/004.Compressor_OpenHamrony-master/code/gradlew.bat b/004.Compressor_OpenHamrony-master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/004.Compressor_OpenHamrony-master/code/settings.gradle b/004.Compressor_OpenHamrony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1e7747a65d578ad1fef59e6363bc23173e306a8a
--- /dev/null
+++ b/004.Compressor_OpenHamrony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':compress'
diff --git "a/004.Compressor_OpenHamrony-master/doc/004 \345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204compress\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/004.Compressor_OpenHamrony-master/doc/004 \345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204compress\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..093c81ef75e3d73c89b9c98c9646153c6d0f199f
Binary files /dev/null and "b/004.Compressor_OpenHamrony-master/doc/004 \345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204compress\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/005.BarGraphView_OpenHarmony-master/code/.gitignore b/005.BarGraphView_OpenHarmony-master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/.gitignore b/005.BarGraphView_OpenHarmony-master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/compiler.xml b/005.BarGraphView_OpenHarmony-master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/gradle.xml b/005.BarGraphView_OpenHarmony-master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0aba8f2b569872e9476b8815733e8bd224bd0311
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/jarRepositories.xml b/005.BarGraphView_OpenHarmony-master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/misc.xml b/005.BarGraphView_OpenHarmony-master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_1167666501.json b/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_1167666501.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_1167666501.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_1272885399.json b/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_1272885399.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_1272885399.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/previewConfig.json b/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..0e35e6427d19d5cedab7af0733c9a51f7693d06b
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/.idea/previewer/previewConfig.json
@@ -0,0 +1,12 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\HarmonyOsChatView\\entry": [
+ "phone"
+ ],
+ "D:\\NEWPATH\\aaa\\HarmonyOsChatView\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/build.gradle b/005.BarGraphView_OpenHarmony-master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..613f3e6a0b18b7a502df3b3655e61411ae191520
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/.gitignore b/005.BarGraphView_OpenHarmony-master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/build.gradle b/005.BarGraphView_OpenHarmony-master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5b676898b964683517e5275b9d2f77aaf52ceed2
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/libs/histogramcomponent-debug.har b/005.BarGraphView_OpenHarmony-master/code/entry/libs/histogramcomponent-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..1f6efcc9811c4fb632f5375ec3673b73cd9543cc
Binary files /dev/null and b/005.BarGraphView_OpenHarmony-master/code/entry/libs/histogramcomponent-debug.har differ
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/config.json b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..fe21426129231827dc20772275d86c6f9da0b54e
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.huawei.harmonyoschatview",
+ "vendor": "huawei",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 3,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.huawei.harmonyoschatview",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.huawei.harmonyoschatview.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:label_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/MainAbility.java b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..61ac828196822ab5c918f5fca124636e42626398
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/MainAbility.java
@@ -0,0 +1,13 @@
+package com.huawei.harmonyoschatview;
+
+import com.huawei.harmonyoschatview.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/MyApplication.java b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..08232b31551c8af6432baf507ec5f91a43803182
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/MyApplication.java
@@ -0,0 +1,10 @@
+package com.huawei.harmonyoschatview;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/slice/MainAbilitySlice.java b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..bebc75382408936d3bd1626f566d0f30f6ef143b
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/java/com/huawei/harmonyoschatview/slice/MainAbilitySlice.java
@@ -0,0 +1,33 @@
+package com.huawei.harmonyoschatview.slice;
+
+import com.huawei.harmonyoschatview.ResourceTable;
+import com.huawei.histogramcomponent.view.HistogramComponent;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+
+public class MainAbilitySlice extends AbilitySlice {
+ private HistogramComponent bargraphview;
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ bargraphview = (HistogramComponent) findComponentById(ResourceTable.Id_bargraphview);
+ // 设置每组柱状图之间的间距
+ bargraphview.mLineSpaceWidth = 30;
+ final int[][] data = {{182, 89, 78, 88}, {34, 85, 16, 96}, {86, 127, 45, 41},{54, 75, 54, 12}};
+ final int[] colorData = {0xFF222233, 0xFFe67656, 0xFF188888,0xFF888888,0xFF888888};
+ final String[] textData = {"一月份", "二月份", "三月份", "四月份"};
+ bargraphview.setBarGraphData(data, colorData, textData);
+
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..f049b6ede4eff6595802d71d2ee59da2cf9e9562
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "HarmonyOsChatView"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "label_name",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3fdf4b51724b46b7fcabb39de0ec3a406adc42bf
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,11 @@
+
+
+
+
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/005.BarGraphView_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/005.BarGraphView_OpenHarmony-master/code/entry/src/test/java/com/huawei/harmonyoschatview/ExampleTest.java b/005.BarGraphView_OpenHarmony-master/code/entry/src/test/java/com/huawei/harmonyoschatview/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..aee120e673467bf21ff3cf9e681c6626bf3f4cb2
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/entry/src/test/java/com/huawei/harmonyoschatview/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.huawei.harmonyoschatview;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/gradle.properties b/005.BarGraphView_OpenHarmony-master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/005.BarGraphView_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar b/005.BarGraphView_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/005.BarGraphView_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/005.BarGraphView_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties b/005.BarGraphView_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/005.BarGraphView_OpenHarmony-master/code/gradlew b/005.BarGraphView_OpenHarmony-master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/005.BarGraphView_OpenHarmony-master/code/gradlew.bat b/005.BarGraphView_OpenHarmony-master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/.gitignore b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/build.gradle b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5e58bb7146b04e3cd72644da4bcf2fae9cbd59bf
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/config.json b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..172625f27c2c324ed14793964cff20f1f110caea
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/config.json
@@ -0,0 +1,28 @@
+{
+ "app": {
+ "bundleName": "com.huawei.harmonyoschatview",
+ "vendor": "huawei",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {
+ },
+ "module": {
+ "package": "com.huawei.histogramcomponent",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "histogramcomponent",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/java/com/huawei/histogramcomponent/view/HistogramComponent.java b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/java/com/huawei/histogramcomponent/view/HistogramComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..12c6b1eaa561f07e73f27a2878b9084e6f80a1f2
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/java/com/huawei/histogramcomponent/view/HistogramComponent.java
@@ -0,0 +1,341 @@
+package com.huawei.histogramcomponent.view;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.DragEvent;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.Point;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class HistogramComponent extends Component {
+ private HiLogLabel hiLogLabel = new HiLogLabel(HiLog.LOG_APP, 0x00101, "文本");
+
+ private Context mContext;
+
+ /**
+ * 柱状图的宽度
+ */
+ public float mLineWidth;
+ /**
+ * 柱状图之间的间隔
+ */
+ public float mLineSpaceWidth;
+ /**
+ * 柱状图的颜色
+ */
+ private int barGraphBgColor;
+ /**
+ * X轴字体的大小
+ */
+ public float mXTextSize;
+ /**
+ * Y轴的字体大小
+ */
+ private float mYTextSize;
+ /**
+ * xy轴线和字体的颜色
+ */
+ private int mXYBGColor;
+ /**
+ * 柱状图执行动画的长度
+ */
+ private Integer duration;
+ /**
+ * 是否显示X轴的文字
+ */
+ private boolean isShowXText;
+ /**
+ * 是否显示Y轴的文字
+ */
+ private boolean isShowYText;
+
+ /**
+ * 柱状图的画笔
+ */
+ private Paint mBarGraphPaint;
+ /**
+ * 柱状图上面字的画笔
+ */
+ private Paint mBarGraphTextPaint;
+ /**
+ * X轴的文字画笔
+ */
+ private Paint mXTextPaint;
+ /**
+ * Y轴的文字画笔
+ */
+ private Paint mYTextPaint;
+ /**
+ * XY轴的坐标画笔
+ */
+ private Paint mXYLinePaint;
+ /**
+ * 当前柱状图的最大高度
+ */
+ private int maxHeight;
+ /**
+ * 实际高度
+ */
+ private int heightMeasureSpec;
+ /**
+ * 实际宽度
+ */
+ private int widthMeasureSpec;
+ /**
+ * 圆柱占用的高度
+ */
+ private float bottomHeight;
+
+ //保存柱状图的数据
+ private int[][] barGraphDataList;
+ //保存柱状图的颜色
+ private int[] barGraphColorList;
+ //保存柱状图X轴信息
+ private String[] barGraphTextList;
+ //Y轴线离左边的距离,以便绘制Y轴数字
+ private float mLeftYWidth;
+ //X轴线离底部的距离,以便绘制X轴的文字
+ private float mBottomXWidth;
+
+
+ /**
+ * 定义DrawTask对象的实例
+ * 这里进行具体的绘画工作
+ */
+ private DrawTask drawTask = new DrawTask() {
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ bottomHeight = heightMeasureSpec - mBottomXWidth;
+ if (barGraphDataList == null || barGraphDataList.length <= 0)
+ return;
+ //画柱状图
+ drawBarGraph(canvas);
+ //画XY轴坐标
+ drawXYLine(canvas);
+ //给XY轴坐标写字
+ drawXYText(canvas);
+ }
+ };
+
+ public HistogramComponent(Context context) {
+ super(context);
+
+ }
+
+ public HistogramComponent(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ this.mContext = context;
+ //柱状图的宽度
+ mLineWidth = 40;
+ //柱状图之间的间隔
+ mLineSpaceWidth = 40;
+ //柱状图的颜色
+ barGraphBgColor = 0xFF222222;
+ //X轴字体大小
+ mXTextSize = 38;
+ //y轴字体大小
+ mYTextSize = 38;
+ //xy轴的颜色
+ mXYBGColor = 0xFF000000;
+ //执行动画的时间
+ duration = 1000;
+ isShowXText = true;
+ isShowYText = true;
+ initView();
+ }
+
+ public HistogramComponent(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+
+ }
+
+ public HistogramComponent(Context context, AttrSet attrSet, int resId) {
+ super(context, attrSet, resId);
+
+ }
+
+ @Override
+ public boolean onDrag(Component component, DragEvent event) {
+ return super.onDrag(component, event);
+
+ }
+
+ @Override
+ public void addDrawTask(DrawTask task) {
+ super.addDrawTask(task);
+ task.onDraw(this,mCanvasForTaskOverContent);
+ }
+
+ /**
+ * 初始化画笔
+ */
+ private void initView() {
+ Display display = DisplayManager.getInstance().getDefaultDisplay(mContext).get();
+ Point point = new Point();
+ display.getSize(point);
+ heightMeasureSpec = MeasureSpec.getSize(point.getPointXToInt());
+ widthMeasureSpec = MeasureSpec.getSize(point.getPointYToInt());
+ if (barGraphDataList != null && barGraphDataList.length > 0) {
+ widthMeasureSpec = (int) (mLineSpaceWidth * (barGraphDataList[0].length + 1) + mLineWidth * barGraphDataList.length * barGraphDataList[0].length) + (5);
+ }
+ this.heightMeasureSpec = MeasureSpec.getSize(heightMeasureSpec);
+ //左边字体的长度
+ widthMeasureSpec += mLeftYWidth + 10;
+
+ mBarGraphPaint = new Paint();
+ mBarGraphPaint.setStrokeWidth(mLineWidth);
+ mBarGraphPaint.setAntiAlias(true);
+
+ mBarGraphTextPaint = new Paint();
+ mBarGraphTextPaint.setStrokeWidth(18.0f);
+ mBarGraphTextPaint.setTextSize(32);
+ mBarGraphTextPaint.setAntiAlias(true);
+
+ mXTextPaint = new Paint();
+ mXTextPaint.setStrokeWidth(13);
+ mXTextPaint.setColor(new Color(mXYBGColor));
+ mXTextPaint.setTextSize((int)mXTextSize);
+ mXTextPaint.setAntiAlias(true);
+
+ mYTextPaint = new Paint();
+ mYTextPaint.setStrokeWidth(13);
+ mYTextPaint.setColor(new Color(mXYBGColor));
+ mYTextPaint.setTextSize((int)mYTextSize);
+ mYTextPaint.setAntiAlias(true);
+
+ mXYLinePaint = new Paint();
+ mXYLinePaint.setStrokeWidth(3);
+ mXYLinePaint.setColor(new Color(mXYBGColor));
+ mXYLinePaint.setAntiAlias(true);
+ addDrawTask(drawTask);
+ }
+
+
+ //画柱状图
+ private void drawBarGraph(Canvas canvas) {
+ if (barGraphDataList != null && barGraphDataList.length > 0) {
+ for (int i = 0; i < barGraphDataList[0].length; i++) {
+ float startX = mLineSpaceWidth * (i + 1) + mLineWidth * barGraphDataList.length * i + mLeftYWidth + (10) + mLineWidth / 2;
+ int index = 0;
+ while (index < barGraphDataList.length) {
+ if (barGraphColorList != null && barGraphColorList.length > index) {
+ mBarGraphPaint.setColor(new Color(barGraphColorList[index]));
+ mBarGraphTextPaint.setColor(new Color(barGraphColorList[index]));
+ } else {
+ mBarGraphPaint.setColor(new Color(barGraphBgColor));
+ mBarGraphTextPaint.setColor(new Color(barGraphBgColor));
+ }
+
+ float stopY = bottomHeight * 0.9f / maxHeight * barGraphDataList[index][i];
+
+ canvas.drawLine(new Point(startX, bottomHeight), new Point(startX, bottomHeight - stopY), mBarGraphPaint);
+
+ String text = String.valueOf(barGraphDataList[index][i]);
+ float textWidth = mBarGraphTextPaint.measureText(text);
+ canvas.drawText(mBarGraphTextPaint,text, startX - textWidth / 2, bottomHeight - stopY - 10);
+ startX += mLineWidth;
+ index++;
+ }
+ }
+ }
+ }
+
+ /**
+ * 传进来的数组要求保持数组长度一致
+ */
+ public void setBarGraphData( int[][] barGraphDataList, int[] barGraphColorList, String[] barGraphTextList) {
+ this.barGraphDataList = barGraphDataList;
+ this.barGraphColorList = barGraphColorList;
+ this.barGraphTextList = barGraphTextList;
+
+ //计算出最高的坐标
+ for (int i = 0; i < barGraphDataList.length; i++) {
+ for (int j = 0; j < barGraphDataList[i].length; j++) {
+ if (maxHeight < barGraphDataList[i][j]) {
+ maxHeight = barGraphDataList[i][j];
+ }
+ }
+ }
+ while (maxHeight % 5 != 0) {
+ maxHeight++;
+ }
+ if (barGraphTextList != null && barGraphTextList.length > 0) {
+ isShowXText = true;
+ }
+ if (isShowYText) {
+ mLeftYWidth = mYTextPaint.measureText(String.valueOf(maxHeight));
+ }
+ mBottomXWidth = (10);
+ if (isShowXText) {
+ Paint.FontMetrics fontMetrics = mXTextPaint.getFontMetrics();
+ mBottomXWidth += ((fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom) * 2;
+ }
+ measureWidth(heightMeasureSpec);
+
+ invalidate();
+ }
+ /**
+ * 长度可能超出屏幕范围
+ */
+ private void measureWidth(int heightMeasureSpec) {
+ if (barGraphDataList != null && barGraphDataList.length > 0) {
+ widthMeasureSpec = (int) (mLineSpaceWidth * (barGraphDataList[0].length + 1) + mLineWidth * barGraphDataList.length * barGraphDataList[0].length) + (5);
+ }
+ this.heightMeasureSpec = MeasureSpec.getSize(heightMeasureSpec);
+ //左边字体的长度
+ widthMeasureSpec += mLeftYWidth + (10);
+ }
+ //画X轴和Y轴的竖线+箭头
+ private void drawXYLine(Canvas canvas) {
+ /**
+ * 让Y轴文字与最左有dip2px(10)的边距
+ * */
+ //Y轴竖线
+ canvas.drawLine(new Point((10) + mLeftYWidth, bottomHeight), new Point((10) + mLeftYWidth, 10), mXYLinePaint);
+ //X轴竖线
+ canvas.drawLine(new Point((10) + mLeftYWidth, bottomHeight), new Point(widthMeasureSpec - 10, bottomHeight), mXYLinePaint);
+ //画个箭头??Y轴
+ canvas.drawLine(new Point((10) + mLeftYWidth, 10), new Point((6) + mLeftYWidth, 20), mXYLinePaint);
+ canvas.drawLine(new Point((10) + mLeftYWidth, 10), new Point((14) + mLeftYWidth, 20), mXYLinePaint);
+ //X轴箭头
+ canvas.drawLine(new Point(widthMeasureSpec - 10, bottomHeight), new Point(widthMeasureSpec - 20, bottomHeight - (4)), mXYLinePaint);
+ canvas.drawLine(new Point(widthMeasureSpec - 10, bottomHeight), new Point(widthMeasureSpec - 20, bottomHeight + (4)), mXYLinePaint);
+ }
+ //给Y轴和X轴写相应的文字
+ private void drawXYText(Canvas canvas) {
+ if (isShowYText) {
+ //Y轴写字
+ for (int i = 1; i <= 5; i++) {
+ float startY = bottomHeight - bottomHeight * 0.9f / maxHeight * maxHeight / 5 * i;
+ canvas.drawLine(new Point((10) + mLeftYWidth, startY), new Point((15) + mLeftYWidth, startY), mYTextPaint);
+ float width = mYTextPaint.measureText(maxHeight / 5 * i + "");
+
+ float dy = 12.0f;
+ canvas.drawText(mYTextPaint,maxHeight / 5 * i + "", (int) ((10) + mLeftYWidth - width - (5)), startY + dy);
+ }
+ }
+ if (!isShowXText) {
+ return;
+ }
+ //X轴写字
+ if (barGraphTextList != null && barGraphTextList.length > 0) {
+ for (int i = 0; i < barGraphTextList.length; i++) {
+ float startX = mLineSpaceWidth * (i + 1) + mLineWidth * barGraphDataList.length * i + mLeftYWidth + (10);
+ //中间有一个间隔
+ startX = startX + (mLineWidth * barGraphDataList.length) * 1.0f / 2;
+ float textWidth = mXTextPaint.measureText(barGraphTextList[i]);
+ canvas.drawText(mXTextPaint,barGraphTextList[i], startX - textWidth / 2, heightMeasureSpec - (5));
+ }
+ }
+ }
+
+ public boolean isShowXText() {
+ return isShowXText;
+ }
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/resources/base/element/string.json b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..f4862bfaa183ab16cd81b5c00ad5b3eaf556d998
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/histogramcomponent/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "HistogramComponent"
+ }
+ ]
+}
diff --git a/005.BarGraphView_OpenHarmony-master/code/settings.gradle b/005.BarGraphView_OpenHarmony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..14d20e55956ee6d12ced1efbd85fe0ff11ec303b
--- /dev/null
+++ b/005.BarGraphView_OpenHarmony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':histogramcomponent'
diff --git "a/005.BarGraphView_OpenHarmony-master/doc/005\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204HistogramComponent\346\237\261\347\212\266\345\233\276\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/005.BarGraphView_OpenHarmony-master/doc/005\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204HistogramComponent\346\237\261\347\212\266\345\233\276\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..64861a700d424eb876c6d5369302358deb3d4457
Binary files /dev/null and "b/005.BarGraphView_OpenHarmony-master/doc/005\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204HistogramComponent\346\237\261\347\212\266\345\233\276\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/.gitignore b/006.PersentPositionLayout_OpenHarmony-master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/.idea/.gitignore b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/.idea/compiler.xml b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/.idea/gradle.xml b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c82750606badcf466701b8ff7729370771a86c5d
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/.idea/jarRepositories.xml b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/.idea/misc.xml b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/build.gradle b/006.PersentPositionLayout_OpenHarmony-master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0e1be68cdeea3cd399f5777b9a7af0797746580f
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/.gitignore b/006.PersentPositionLayout_OpenHarmony-master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/build.gradle b/006.PersentPositionLayout_OpenHarmony-master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..503b2e6af53b17acdb1dc82be812e1a65beca1f4
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/libs/precentpositionlayout.har b/006.PersentPositionLayout_OpenHarmony-master/code/entry/libs/precentpositionlayout.har
new file mode 100644
index 0000000000000000000000000000000000000000..c697b301fa575a2756b6f3eb4336ac4e22660a29
Binary files /dev/null and b/006.PersentPositionLayout_OpenHarmony-master/code/entry/libs/precentpositionlayout.har differ
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/config.json b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..9d38e21bfe76009481fbe6fb5b91b39d8b97b881
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.layouttest",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.layouttest",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.isoftstone.layouttest.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:label_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/MainAbility.java b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..2af01cb8e0f1bf7493a592b9f3fceac68dba92d6
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/MainAbility.java
@@ -0,0 +1,13 @@
+package com.isoftstone.layouttest;
+
+import com.isoftstone.layouttest.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/MyApplication.java b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6cf21b26ab726ed074ffd2fc24ccfaced21c741
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/MyApplication.java
@@ -0,0 +1,10 @@
+package com.isoftstone.layouttest;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/slice/MainAbilitySlice.java b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b949eb9bbdac74b4beacf0ae084f1df270e8ae6
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/java/com/isoftstone/layouttest/slice/MainAbilitySlice.java
@@ -0,0 +1,33 @@
+package com.isoftstone.layouttest.slice;
+
+import com.isoftstone.layouttest.ResourceTable;
+import com.isoftstone.precentpositionlayout.PrecentPositionLayout;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.LayoutScatter;
+
+public class MainAbilitySlice extends AbilitySlice {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ // 解析xml文件
+ PrecentPositionLayout precentPositionLayout = (PrecentPositionLayout)LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_ability_main, null, false);
+
+ // 调用precentPositionLayout 的Autosize方法
+ precentPositionLayout.AutoSize();
+
+ super.setUIContent(precentPositionLayout);
+
+ //super.setUIContent(ResourceTable.Layout_ability_main);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..466ba6f52b45260a73f3413b3afd46ba03640fb9
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "LayoutTest"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "label_name",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_text.xml b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_text.xml
new file mode 100644
index 0000000000000000000000000000000000000000..632ac8886e0fb78f2f12193f08f098768ed8c752
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_text.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..add478b0b96b9a5235ba3230f652309bc16de2ae
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/test/java/com/isoftstone/layouttest/ExampleTest.java b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/test/java/com/isoftstone/layouttest/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0dbf7effda01a535560a18979968e77debd41138
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/entry/src/test/java/com/isoftstone/layouttest/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.isoftstone.layouttest;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/gradle.properties b/006.PersentPositionLayout_OpenHarmony-master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar b/006.PersentPositionLayout_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/006.PersentPositionLayout_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties b/006.PersentPositionLayout_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/gradlew b/006.PersentPositionLayout_OpenHarmony-master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/gradlew.bat b/006.PersentPositionLayout_OpenHarmony-master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/.gitignore b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/build.gradle b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5e58bb7146b04e3cd72644da4bcf2fae9cbd59bf
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/config.json b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..75ab7820217bc7da835a520cb4fcffbe05d1390a
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/config.json
@@ -0,0 +1,28 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.layouttest",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {
+ },
+ "module": {
+ "package": "com.isoftstone.precentpositionlayout",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "precentpositionlayout",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/java/com/isoftstone/precentpositionlayout/PrecentPositionLayout.java b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/java/com/isoftstone/precentpositionlayout/PrecentPositionLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..e361971e85007101dca27f94f3a74d24fb189de4
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/java/com/isoftstone/precentpositionlayout/PrecentPositionLayout.java
@@ -0,0 +1,54 @@
+package com.isoftstone.precentpositionlayout;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.PositionLayout;
+import ohos.agp.utils.Point;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+
+import java.util.Optional;
+
+public class PrecentPositionLayout extends PositionLayout {
+ public PrecentPositionLayout(Context context) {
+ super(context);
+ }
+
+ public PrecentPositionLayout(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ }
+
+ public PrecentPositionLayout(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ }
+
+
+ /* 调整各组件的大小,按照百分比调整
+ * 将原来组件的起始位置,宽度和高度都视作相对于整个屏幕的百分比值,然后根据屏幕的分辨率转换为实际的像素值。
+ * 注:考虑到使用0-100配置百分比的话,范围太小不够精确,因此配置范围设置为0-1000,
+ * 比如当前屏幕是1920 * 1060, 某个组件的宽度和高度配置的是200,则表示改组件的宽和高都占整个屏幕的20%。
+ * 因此,调整后改组件的实际大小为384 * 212.
+ */
+ public void AutoSize() {
+ // 获取屏幕分辨率
+ Optional display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
+ Point pt = new Point();
+ display.get().getSize(pt);
+
+ // 去除上面标题栏和下面导航栏的高度
+ pt.modify(pt.getPointX(), pt.getPointY() - 160);
+
+ // 调增各组件的大小
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ Component component = getComponentAt(i);
+ ComponentContainer.LayoutConfig config = component.getLayoutConfig();
+ component.setLeft(config.getMarginLeft() * pt.getPointXToInt() / 1000);
+ component.setTop(config.getMarginTop() * pt.getPointYToInt() / 1000);
+ component.setWidth(config.width * pt.getPointXToInt() / 1000);
+ component.setHeight(config.height * pt.getPointYToInt() / 1000);
+ }
+ }
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/resources/base/element/string.json b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..ec8bf163522d86c2770650344123f5a9b5f342c0
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/precentpositionlayout/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "PrecentPositionLayout"
+ }
+ ]
+}
diff --git a/006.PersentPositionLayout_OpenHarmony-master/code/settings.gradle b/006.PersentPositionLayout_OpenHarmony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..56682ff375d1007f26811f3a4ee74a9d460723db
--- /dev/null
+++ b/006.PersentPositionLayout_OpenHarmony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':precentpositionlayout'
diff --git "a/006.PersentPositionLayout_OpenHarmony-master/doc/006.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PrecentPositionLayout\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/006.PersentPositionLayout_OpenHarmony-master/doc/006.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PrecentPositionLayout\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..8de3674f3f40279ffac8070b2eaae59093007c05
Binary files /dev/null and "b/006.PersentPositionLayout_OpenHarmony-master/doc/006.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PrecentPositionLayout\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.gitignore b/007.PolygonImageView_OpenHarmony_master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/.gitignore b/007.PolygonImageView_OpenHarmony_master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/compiler.xml b/007.PolygonImageView_OpenHarmony_master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/gradle.xml b/007.PolygonImageView_OpenHarmony_master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1a32c3f6a9c6576cf88bcec372f3584c887fb15e
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/jarRepositories.xml b/007.PolygonImageView_OpenHarmony_master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/misc.xml b/007.PolygonImageView_OpenHarmony_master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-1729565748.json b/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-1729565748.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-1729565748.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_1421648561.json b/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_1421648561.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_1421648561.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/previewConfig.json b/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..f5223da6b9d95e7b86d508b340ae050a63662c07
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/.idea/previewer/previewConfig.json
@@ -0,0 +1,12 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "E:\\workspace\\HarmonyOS\\DevEcoStudioProjects\\PolygonImageView\\entry": [
+ "phone"
+ ],
+ "D:\\PCFile\\PCFile\\svn\\052.PolygonImageView_error\\PolygonImageView\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/build.gradle b/007.PolygonImageView_OpenHarmony_master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0da9bc913f7350fad9087d8535f200bedce92ed3
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/.gitignore b/007.PolygonImageView_OpenHarmony_master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/build.gradle b/007.PolygonImageView_OpenHarmony_master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..faa5f12f03ced88d0f393fa2131312ab29b37cc1
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ compile project(path: ':polygonimageview')
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/config.json b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..bc87c113ba678df3fca15d937605dba18cadd3c6
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.polygonimageview",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.polygonimageview",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.isoftstone.polygonimageview.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:label_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/MainAbility.java b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..49721c3088445a52e3b0ec5a522f1d20f3e51482
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/MainAbility.java
@@ -0,0 +1,13 @@
+package com.isoftstone.polygonimageview;
+
+import com.isoftstone.polygonimageview.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/MyApplication.java b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..e86a3f2194952b9029f49b0f1fd51e63e091d806
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/MyApplication.java
@@ -0,0 +1,10 @@
+package com.isoftstone.polygonimageview;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/slice/MainAbilitySlice.java b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..2bcdb856993303dbc23f240937d181133cc5eab7
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/polygonimageview/slice/MainAbilitySlice.java
@@ -0,0 +1,102 @@
+package com.isoftstone.polygonimageview.slice;
+
+import com.isoftstone.polygonimageview.ResourceTable;
+import com.isoftstone.polygonimageview.shapes.PaperPolygonShape;
+import com.isoftstone.polygonimageview.shapes.RegularPolygonShape;
+import com.isoftstone.polygonimageview.shapes.StarPolygonShape;
+import com.isoftstone.polygonimageview.view.PolygonImageView;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.ScrollView;
+import ohos.agp.utils.Color;
+
+public class MainAbilitySlice extends AbilitySlice {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ PolygonImageView imageView = (PolygonImageView) findComponentById(ResourceTable.Id_cat04);
+
+ DirectionalLayout layout = (DirectionalLayout) findComponentById(ResourceTable.Id_layout);
+
+ PolygonImageView view = new PolygonImageView(this);
+ view.setPixelMap(ResourceTable.Media_cat05);
+
+ view.addShadow(10f, 0f, 0f, Color.RED.getValue());
+ view.addBorder(10, Color.WHITE);
+ view.setCornerRadius(10);
+ view.setVertices(16);
+ view.setMarginTop(20);
+
+ view.setPolygonShape(new StarPolygonShape(0.8f, false));
+ layout.addComponent(view, imageView.getLayoutConfig());
+
+ PolygonImageView view2 = new PolygonImageView(this);
+ view2.setPixelMap(ResourceTable.Media_cat06);
+ view2.addShadow(15f, 0f, 0f, Color.BLACK.getValue());
+ view2.addBorder(10, Color.WHITE);
+ view2.setCornerRadius(10);
+ view2.setVertices(24);
+ view2.setMarginTop(20);
+
+ view2.setPolygonShape(new StarPolygonShape(0.8f, false));
+ layout.addComponent(view2, imageView.getLayoutConfig());
+
+ PolygonImageView view7 = new PolygonImageView(this);
+ view7.setPixelMap(ResourceTable.Media_cat06);
+ view7.addShadow(15f, 0f, 0f, Color.BLACK.getValue());
+ view7.addBorder(10, Color.WHITE);
+ view7.setCornerRadius(10);
+ view7.setVertices(8);
+ view7.setMarginTop(20);
+
+ view7.setPolygonShape(new StarPolygonShape(0.8f, true));
+
+ layout.addComponent(view7, imageView.getLayoutConfig());
+
+ PolygonImageView view3 = new PolygonImageView(this);
+ view3.setPixelMap(ResourceTable.Media_cat07);
+ view3.addShadowResource(10f, 0f, 7.5f, ResourceTable.Color_shadow);
+ view3.addBorderResource(10, ResourceTable.Color_border);
+ view3.setCornerRadius(2);
+ view3.setVertices(5);
+ view3.setMarginTop(20);
+
+// view3.setPolygonShape(new PaperPolygonShape(-15, 25));
+ view3.setPolygonShape(new StarPolygonShape(0.8f, true));
+ layout.addComponent(view3, imageView.getLayoutConfig());
+
+
+ PolygonImageView view4 = new PolygonImageView(this);
+ view4.setPixelMap(ResourceTable.Media_cat04);
+ view4.addShadowResource(7.5f, 0f, 0f, Color.YELLOW);
+ view4.addBorderResource(5, Color.GREEN);
+ view4.setBorder(true);
+ view4.setMarginTop(20);
+
+ view4.setPolygonShape(new PaperPolygonShape(-15,20));
+ layout.addComponent(view4, imageView.getLayoutConfig());
+
+ PolygonImageView view5 = new PolygonImageView(this);
+ view5.setPixelMap(ResourceTable.Media_cat02);
+ view5.addShadowResource(20f, 0f, 7.5f, Color.BLUE);
+ view5.addBorderResource(20, Color.RED);
+ view5.setCornerRadius(5);
+ view5.setVertices(6);
+ view5.setMarginTop(20);
+ view5.setPolygonShape(new RegularPolygonShape());
+ layout.addComponent(view5, imageView.getLayoutConfig());
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/element/color.json b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..5f870205ee0ffb5be944776d2af0088e541d1be7
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,12 @@
+{
+ "color": [
+ {
+ "name": "border",
+ "value": "#B2FF59"
+ },
+ {
+ "name": "shadow",
+ "value": "#7CB342"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/element/string.json b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..87784922edc284cdf7230d77ed22102d3c43f419
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "PolygonImageView"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "label_name",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/layout/ability_main.xml b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..688c68555710841b4612141186ca1e45a5bcb69a
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat01.jpg b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat01.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..595732d03f94e3592e23942e81e29647e6ecdbce
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat01.jpg differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat02.jpg b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat02.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..67e4c04bd3b44d49d8a5b3dad1c1275dbf4a57ec
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat02.jpg differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat03.jpg b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat03.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..583c52559bfefa2c8db27ba90e0bea7fb6245be1
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat03.jpg differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat04.jpg b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat04.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..268f0d9a44a45ff1ef5435f6a54dd3bb0525e0ac
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat04.jpg differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat05.jpg b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat05.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5ae4bfa998afbe25c52c551016917373c13b850c
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat05.jpg differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat06.jpg b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat06.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5da1f5ee398d135c12cf48df6e5d0db1431d83cf
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat06.jpg differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat07.jpg b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat07.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..75d4182c587a9433b511e6c0633113f8d3ab88ec
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/cat07.jpg differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/icon.png b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/entry/src/test/java/com/isoftstone/polygonimageview/ExampleTest.java b/007.PolygonImageView_OpenHarmony_master/code/entry/src/test/java/com/isoftstone/polygonimageview/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3dc5b851059c019e8302cddf6ada05c5152c3ad
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/entry/src/test/java/com/isoftstone/polygonimageview/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.isoftstone.polygonimageview;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/gradle.properties b/007.PolygonImageView_OpenHarmony_master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/007.PolygonImageView_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.jar b/007.PolygonImageView_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/007.PolygonImageView_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/007.PolygonImageView_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.properties b/007.PolygonImageView_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/007.PolygonImageView_OpenHarmony_master/code/gradlew b/007.PolygonImageView_OpenHarmony_master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/007.PolygonImageView_OpenHarmony_master/code/gradlew.bat b/007.PolygonImageView_OpenHarmony_master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/.gitignore b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/build.gradle b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/config.json b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..9a67a467aec666406a4a8955a53160ef30ef23ed
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.polygonimageview",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.polygonimageview",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "polygonimageview",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/BasePolygonShape.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/BasePolygonShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..2dd22bead9d8cf7f1f9b585fc9652b93b7e4cbb6
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/BasePolygonShape.java
@@ -0,0 +1,94 @@
+package com.isoftstone.polygonimageview.shapes;
+
+import ohos.agp.render.Path;
+
+/**
+ * Base abstract class for implementation shape interface
+ */
+public abstract class BasePolygonShape implements PolygonShape {
+
+ /**
+ * 多边形路径
+ */
+ private Path mPath;
+ /**
+ * 多边形
+ */
+ private PolygonShapeSpec polygonShapeSpec;
+
+ /**
+ * 构造方法
+ */
+ public BasePolygonShape() {
+ this.mPath = new Path();
+ }
+
+ /**
+ * Return a valid closed path
+ *
+ * @param spec shape specs
+ * @return a Path
+ */
+ @Override
+ public Path getPolygonPath(PolygonShapeSpec spec) {
+ float pointX, pointY, rotatedPointX, rotatedPointY, currentPointX = 0f, currentPointY = 0f;
+ double angleRadians = Math.toRadians(spec.getRotation());
+ polygonShapeSpec = spec;
+
+ mPath.reset();
+ int i = 0;
+ do {
+ //next vertex point
+ pointX = spec.getCenterX() + spec.getDiameter() / 2f *
+ (float) Math.cos(2 * Math.PI * i / spec.getNumVertex());
+ pointY = spec.getCenterY() + spec.getDiameter() / 2f *
+ (float) Math.sin(2 * Math.PI * i / spec.getNumVertex());
+ //rotate vertex
+ rotatedPointX = (float) (Math.cos(angleRadians) * (pointX - spec.getCenterX()) -
+ Math.sin(angleRadians) * (pointY - spec.getCenterY()) + spec.getCenterX());
+ rotatedPointY = (float) (Math.sin(angleRadians) * (pointX - spec.getCenterX()) +
+ Math.cos(angleRadians) * (pointY - spec.getCenterY()) + spec.getCenterY());
+
+ if (i == 0) { //move to first vertex
+ mPath.moveTo(rotatedPointX, rotatedPointY);
+ } else {
+ //how to draw to next point
+ addEffect(currentPointX, currentPointY, rotatedPointX, rotatedPointY);
+ }
+
+ currentPointX = rotatedPointX;
+ currentPointY = rotatedPointY;
+ i++;
+ } while (i <= spec.getNumVertex());
+ mPath.close();
+
+ return mPath;
+ }
+
+ /**
+ * 获取多边形绘制路径
+ * @return 多边形绘制路径
+ */
+ public Path getPath() {
+ return mPath;
+ }
+
+ /**
+ * 获取具体实现多边形对象
+ * @return 多边形对象
+ */
+ public PolygonShapeSpec getPolygonShapeSpec() {
+ return polygonShapeSpec;
+ }
+
+ /**
+ * Indicates how to draw to next point
+ *
+ * @param currentX current point x
+ * @param currentY current point y
+ * @param nextX next point x
+ * @param nextY next point y
+ */
+ abstract protected void addEffect(float currentX, float currentY, float nextX, float nextY);
+
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PaperPolygonShape.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PaperPolygonShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..9deceb802ce9f63ccdf0dfdebaa9f9517ebb04b9
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PaperPolygonShape.java
@@ -0,0 +1,72 @@
+package com.isoftstone.polygonimageview.shapes;
+
+/**
+ * 平滑的二次贝塞尔曲线效果
+ */
+public class PaperPolygonShape extends BasePolygonShape {
+ /**
+ * 画笔X方向偏移量
+ */
+ private int brushOffsetX;
+ /**
+ * 画笔Y方向偏移量
+ */
+ private int brushOffsetY;
+
+ /**
+ * 构造方法
+ * @param brushOffsetX 画笔X方向偏移量
+ * @param brushOffsetY 画笔Y方向偏移量
+ */
+ public PaperPolygonShape(int brushOffsetX, int brushOffsetY) {
+ super();
+ this.brushOffsetX = brushOffsetX;
+ this.brushOffsetY = brushOffsetY;
+ }
+
+ @Override
+ protected void addEffect(float currentX, float currentY, float nextX, float nextY) {
+ getPath().quadTo(nextX + brushOffsetX, nextY + brushOffsetY, nextX, nextY);
+ }
+
+ /**
+ * 获取画笔X方向偏移量
+ * @return 画笔X方向偏移量
+ */
+ public int getBrushOffsetX() {
+ return brushOffsetX;
+ }
+
+ /**
+ * 设置画笔X方向偏移量
+ * @param brushOffsetX 画笔X方向偏移量
+ */
+ public void setBrushOffsetX(int brushOffsetX) {
+ this.brushOffsetX = brushOffsetX;
+ }
+
+ /**
+ * 获取画笔Y方向偏移量
+ * @return 画笔Y方向偏移量
+ */
+ public int getBrushOffsetY() {
+ return brushOffsetY;
+ }
+ /**
+ * 设置画笔Y方向偏移量
+ * @param brushOffsetY 画笔Y方向偏移量
+ */
+ public void setBrushOffsetY(int brushOffsetY) {
+ this.brushOffsetY = brushOffsetY;
+ }
+
+ /**
+ * 更新偏移量
+ * @param brushOffsetX 画笔X方向偏移量
+ * @param brushOffsetY 画笔Y方向偏移量
+ */
+ public void updateOffsets(int brushOffsetX, int brushOffsetY) {
+ setBrushOffsetX(brushOffsetX);
+ setBrushOffsetY(brushOffsetY);
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PolygonShape.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PolygonShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..996ab2f3e7afa64d200bccd8d8b7414a69a715a6
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PolygonShape.java
@@ -0,0 +1,17 @@
+package com.isoftstone.polygonimageview.shapes;
+
+import ohos.agp.render.Path;
+
+/**
+ * Interface for set a custom polygon shape
+ */
+public interface PolygonShape {
+
+ /**
+ * Return a closed valid Path
+ *
+ * @param polygonShapeSpec polygonal specs
+ * @return a Path
+ */
+ Path getPolygonPath(PolygonShapeSpec polygonShapeSpec);
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PolygonShapeSpec.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PolygonShapeSpec.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfd944ed5fb5b67ec6db551104dcf2d5f4e2d7bb
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/PolygonShapeSpec.java
@@ -0,0 +1,347 @@
+package com.isoftstone.polygonimageview.shapes;
+
+import ohos.agp.utils.Color;
+
+/**
+ * Basic specification for a shape
+ * @author xxhuangd
+ */
+public class PolygonShapeSpec {
+ /**
+ * 默认阴影半径
+ */
+ private static final float DEFAULT_SHADOW_RADIUS = 7.5f;
+ /**
+ * 默认阴影颜色
+ */
+ private static final Color DEFAULT_SHADOW_COLOR = Color.BLACK;
+
+ /**
+ * 默认边框颜色
+ */
+ private static final Color DEFAULT_BOARD_COLOR = Color.WHITE;
+ /**
+ * 默认阴影X偏移量
+ */
+ private static final float DEFAULT_X_OFFSET = 0f;
+ /**
+ * 默认阴影Y偏移量
+ */
+ private static final float DEFAULT_Y_OFFSET = 0f;
+ /**
+ * 旋转角度
+ */
+ private float rotation;
+ /**
+ * 多边形定点个数
+ */
+ private int numVertex;
+ /**
+ * 多边形是否有边框
+ */
+ private boolean hasBorder;
+ /**
+ * 多边形拐角半径
+ */
+ private float cornerRadius;
+ /**
+ * 多边形边框颜色
+ */
+ private Color borderColor;
+ /**
+ * 多边形边框宽度
+ */
+ private float borderWidth;
+ /**
+ * 多边形是否有阴影
+ */
+ private boolean hasShadow;
+ /**
+ * 多边形阴影半径
+ */
+ private float shadowRadius;
+ /**
+ * 多边形阴影偏移量
+ */
+ private float shadowXOffset, shadowYOffset;
+ /**
+ * 多边形阴影颜色
+ */
+ private Color shadowColor;
+
+ /**
+ * 多边形直径
+ */
+ private float diameter;
+ /**
+ * 多边形中心点坐标
+ */
+ private float centerX, centerY;
+
+ /**
+ * 构造方法
+ */
+ public PolygonShapeSpec() {
+ defaultShadow();
+ }
+
+ /**
+ * 构造方法
+ * @param centerX 中心点X左标
+ * @param centerY 中心点Y坐标
+ * @param diameter 直径
+ * @param numVertex 顶点个数
+ * @param rotation 旋转角度
+ */
+ public PolygonShapeSpec(float centerX, float centerY, float diameter, int numVertex, float rotation) {
+ this.centerX = centerX;
+ this.centerY = centerY;
+ this.diameter = diameter;
+ this.numVertex = numVertex;
+ this.rotation = rotation;
+
+ defaultShadow();
+ }
+
+ /**
+ * 获取边框颜色
+ * @return 边框颜色
+ */
+ public Color getBorderColor() {
+ return borderColor;
+ }
+
+ /**
+ * 设置边框颜色
+ * @param borderColor 边框颜色
+ */
+ public void setBorderColor(Color borderColor) {
+ this.borderColor = borderColor;
+ }
+
+ /**
+ * 获取边框宽度
+ * @return 边框宽度
+ */
+ public float getBorderWidth() {
+ return borderWidth;
+ }
+
+ /**
+ * 设置边框宽度
+ * @param borderWidth 边框宽度
+ */
+ public void setBorderWidth(float borderWidth) {
+ this.borderWidth = borderWidth;
+ }
+
+ /**
+ * 获取中心点X坐标
+ * @return 中心点X坐标
+ */
+ public float getCenterX() {
+ return centerX;
+ }
+
+ /**
+ * 设置中心点X坐标
+ * @param centerX 中心点X坐标
+ */
+ public void setCenterX(float centerX) {
+ this.centerX = centerX;
+ }
+ /**
+ * 获取中心点Y坐标
+ * @return 中心点Y坐标
+ */
+ public float getCenterY() {
+ return centerY;
+ }
+ /**
+ * 设置中心点Y坐标
+ * @param centerY 中心点Y坐标
+ */
+ public void setCenterY(float centerY) {
+ this.centerY = centerY;
+ }
+
+ /**
+ * 获取拐角半径
+ * @return 拐角半径
+ */
+ public float getCornerRadius() {
+ return cornerRadius;
+ }
+
+ /**
+ * 查询拐角半径
+ * @param cornerRadius 拐角半径
+ */
+ public void setCornerRadius(float cornerRadius) {
+ this.cornerRadius = cornerRadius;
+ }
+
+ /**
+ * 查询直经
+ * @return 直经
+ */
+ public float getDiameter() {
+ return diameter;
+ }
+
+ /**
+ * 设置直径
+ * @param diameter 直经
+ */
+ public void setDiameter(float diameter) {
+ this.diameter = diameter;
+ }
+
+ /**
+ * 是否有阴影
+ * @return 是否有阴影
+ */
+ public boolean hasShadow() {
+ return hasShadow;
+ }
+
+ /**
+ * 设置阴影
+ * @param hasShadow 是否有阴影
+ */
+ public void setHasShadow(boolean hasShadow) {
+ this.hasShadow = hasShadow;
+ if(!this.hasShadow)
+ defaultShadow();
+ }
+
+ /**
+ * 是否包含边框
+ * @return 是否有边框
+ */
+ public boolean hasBorder() {
+ return hasBorder;
+ }
+
+ /**
+ * 设置边框
+ * @param hasBorder 是否有边框
+ */
+ public void setHasBorder(boolean hasBorder) {
+ this.hasBorder = hasBorder;
+ }
+
+ /**
+ * 获取阴影X方向偏移量
+ * @return X方向偏移量
+ */
+ public float getShadowXOffset() {
+ return shadowXOffset;
+ }
+
+ /**
+ * 设置阴影X方向偏移量
+ * @param shadowXOffset X方向偏移量
+ */
+ public void setShadowXOffset(float shadowXOffset) {
+ this.shadowXOffset = shadowXOffset;
+ }
+ /**
+ * 获取阴影Y方向偏移量
+ * @return Y方向偏移量
+ */
+ public float getShadowYOffset() {
+ return shadowYOffset;
+ }
+ /**
+ * 设置阴影Y方向偏移量
+ * @param shadowYOffset Y方向偏移量
+ */
+ public void setShadowYOffset(float shadowYOffset) {
+ this.shadowYOffset = shadowYOffset;
+ }
+
+ /**
+ * 获取阴影半径
+ * @return 阴影半径
+ */
+ public float getShadowRadius() {
+ return shadowRadius;
+ }
+
+ /**
+ * 设置阴影半径
+ * @param shadowRadius 阴影半径
+ */
+ public void setShadowRadius(float shadowRadius) {
+ this.shadowRadius = shadowRadius;
+ }
+
+ /**
+ * 获取阴影颜色
+ * @return 阴影颜色
+ */
+ public Color getShadowColor() {
+ return shadowColor;
+ }
+
+ /**
+ * 设置阴影颜色
+ * @param shadowColor 阴影颜色
+ */
+ public void setShadowColor(Color shadowColor) {
+ this.shadowColor = shadowColor;
+ }
+
+ /**
+ * 获取顶底个数
+ * @return 顶底个数
+ */
+ public int getNumVertex() {
+ return numVertex;
+ }
+
+ /**
+ * 设置顶点个数
+ * @param numVertex 顶点个数
+ */
+ public void setNumVertex(int numVertex) {
+ this.numVertex = numVertex;
+ }
+ /**
+ * 获取旋转角度
+ * @return 旋转角度
+ */
+ public float getRotation() {
+ return rotation;
+ }
+ /**
+ * 设置旋转角度
+ * @param rotation 旋转角度
+ */
+ public void setRotation(float rotation) {
+ this.rotation = rotation;
+ }
+
+ /**
+ * 更新多边形位置信息
+ * @param centerX 中心点X坐标
+ * @param centerY 中心点Y坐标
+ * @param diameter 直径
+ */
+ public void updatePosition(float centerX, float centerY, float diameter) {
+ setCenterX(centerX);
+ setCenterY(centerY);
+ setDiameter(diameter);
+ }
+
+ /**
+ * 设置默认阴影信息
+ */
+ private void defaultShadow() {
+ shadowRadius = DEFAULT_SHADOW_RADIUS;
+ shadowXOffset = DEFAULT_X_OFFSET;
+ shadowYOffset = DEFAULT_Y_OFFSET;
+ shadowColor = DEFAULT_SHADOW_COLOR;
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/RegularPolygonShape.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/RegularPolygonShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..feb4aa08f604dc09e320113031546de0832a4e5a
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/RegularPolygonShape.java
@@ -0,0 +1,13 @@
+package com.isoftstone.polygonimageview.shapes;
+
+/**
+ * 正常多边形直线效果
+ *
+ */
+public class RegularPolygonShape extends BasePolygonShape {
+
+ @Override
+ protected void addEffect(float currentX, float currentY, float nextX, float nextY) {
+ getPath().lineTo(nextX, nextY);
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/StarPolygonShape.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/StarPolygonShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb40f84b9e7c714f3acd36dacf534e03190186b3
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/shapes/StarPolygonShape.java
@@ -0,0 +1,82 @@
+package com.isoftstone.polygonimageview.shapes;
+
+import com.isoftstone.polygonimageview.view.util.GeometryUtil;
+
+import java.util.List;
+
+/**
+ * 星形效果的多边形
+ * @author xxhuangd
+ */
+public class StarPolygonShape extends BasePolygonShape {
+ /**
+ * 半经
+ */
+ private float radiusScale;
+ /**
+ * 是否凹面
+ */
+ private boolean isConcave;
+
+ /**
+ * 构造方法
+ * @param valor 半径
+ * @param isConcave 是否凹面
+ */
+ public StarPolygonShape(float valor, boolean isConcave) {
+ this.radiusScale = valor;
+ this.isConcave = isConcave;
+ }
+
+ @Override
+ protected void addEffect(float currentX, float currentY, float nextX, float nextY) {
+ float cX = getPolygonShapeSpec().getCenterX();
+ float cY = getPolygonShapeSpec().getCenterY();
+ float radius = (getPolygonShapeSpec().getDiameter() / 2f) * radiusScale;
+
+ float pX = (currentX + nextX) / 2f;
+ float pY = (currentY + nextY) / 2f;
+
+ List p = GeometryUtil.getCircleLineIntersectionPoint(new GeometryUtil.Point(pX, pY),
+ new GeometryUtil.Point(cX, cY), new GeometryUtil.Point(cX, cY), radius);
+
+ if (isConcave) {
+ getPath().quadTo((float) p.get(0).x, (float) p.get(0).y, nextX, nextY);
+ } else {
+ getPath().lineTo((float) p.get(0).x, (float) p.get(0).y);
+ getPath().lineTo(nextX, nextY);
+ }
+ }
+
+ /**
+ * 是否凹面效果
+ * @return 是否凹面效果
+ */
+ public boolean isConcave() {
+ return isConcave;
+ }
+
+ /**
+ * 设置是否有凹面效果
+ * @param isConcave 是否有凹面效果
+ */
+ public void setIsConcave(boolean isConcave) {
+ this.isConcave = isConcave;
+ }
+
+ /**
+ * 获取半径
+ * @return 半径
+ */
+ public float getRadiusScale() {
+ return radiusScale;
+ }
+
+ /**
+ * 设置半径
+ * @param radiusScale
+ */
+ public void setRadiusScale(float radiusScale) {
+ this.radiusScale = radiusScale;
+ }
+}
\ No newline at end of file
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/view/PolygonImageView.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/view/PolygonImageView.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d407c1fc5a1c1bb7ed6305aa808b4be3a99e91e
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/view/PolygonImageView.java
@@ -0,0 +1,823 @@
+/*
+ * Copyright (C) 2014 Albert Grobas
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.isoftstone.polygonimageview.view;
+
+import com.isoftstone.polygonimageview.shapes.PolygonShape;
+import com.isoftstone.polygonimageview.shapes.PolygonShapeSpec;
+import com.isoftstone.polygonimageview.shapes.RegularPolygonShape;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.components.element.Element;
+import ohos.agp.render.*;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.Matrix;
+import ohos.agp.utils.RectFloat;
+import ohos.app.Context;
+import ohos.global.resource.NotExistException;
+import ohos.global.resource.WrongTypeException;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+import ohos.media.image.common.PixelFormat;
+import ohos.media.image.common.Rect;
+import ohos.media.image.common.ScaleMode;
+import ohos.media.image.common.Size;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Construct a custom ImageView with a regular polygonal form.
+ * The number of vertices determines the polygon form.
+ * Special cases for vertex number are:
+ * 0 -> Circle
+ * 1 -> Regular ImageView
+ * 2 -> Square
+ * Use square images
+ *
+ */
+public class PolygonImageView extends Image implements Component.LayoutRefreshedListener, Component.DrawTask {
+
+ /**
+ * 日志标签
+ */
+ private static HiLogLabel LABLE = new HiLogLabel(HiLog.LOG_APP, 0x000115, "PolygonImageView");
+ /**
+ * 图形画笔
+ */
+ private Paint mPaint;
+ /**
+ * 边框画笔
+ */
+ private Paint mBorderPaint;
+ /**
+ * 绘制路径
+ */
+ private Path mPath;
+
+ /**
+ * 多边形
+ */
+ private PolygonShape mPolygonShape;
+ /**
+ * 多边形
+ */
+ private PolygonShapeSpec mPolygonShapeSpec;
+
+ /**
+ * 画布尺寸
+ */
+ private int canvasWidth, canvasHeight;
+
+ private final Matrix mShaderMatrix = new Matrix();
+
+ /**
+ * 背景图片
+ */
+ private PixelMap mPixelMap;
+
+
+ /**
+ * 构造方法
+ * @param context 上下文
+ */
+ public PolygonImageView(Context context) {
+ this(context,null);
+ }
+
+ /**
+ * 构造方法
+ * @param context 上下文
+ * @param attrs xml属性
+ */
+ public PolygonImageView(Context context, AttrSet attrs) {
+ this(context, attrs,"");
+ }
+
+ /**
+ * 构造方法
+ * @param context 上下文
+ * @param attrs xml属性
+ * @param defStyle 风格样式
+ */
+ public PolygonImageView(Context context, AttrSet attrs, String defStyle) {
+ super(context, attrs, defStyle);
+ HiLog.error(LABLE, "PolygonImageView初始化");
+ mPolygonShapeSpec = new PolygonShapeSpec();
+
+ if(attrs != null) {
+ if (attrs.getAttr("poly_rotation_angle").isPresent()) {
+ HiLog.error(LABLE, "自定义angle");
+ mPolygonShapeSpec.setRotation(attrs.getAttr("poly_rotation_angle").get().getFloatValue());
+ } else {
+ HiLog.error(LABLE, "default angle");
+ }
+
+ if (attrs.getAttr("poly_vertices").isPresent()) {
+ HiLog.error(LABLE, "自定义poly_vertices");
+ mPolygonShapeSpec.setNumVertex(attrs.getAttr("poly_vertices").get().getIntegerValue());
+ } else {
+ HiLog.error(LABLE, "default poly_vertices");
+ }
+
+ if (attrs.getAttr("poly_corner_radius").isPresent()) {
+ HiLog.error(LABLE, "自定义poly_corner_radius");
+ mPolygonShapeSpec.setCornerRadius(attrs.getAttr("poly_corner_radius").get().getFloatValue());
+ } else {
+ HiLog.error(LABLE, "default poly_corner_radius");
+ }
+
+ if (attrs.getAttr("poly_shadow").isPresent()) {
+ HiLog.error(LABLE, "自定义poly_shadow");
+ mPolygonShapeSpec.setHasShadow(attrs.getAttr("poly_shadow").get().getBoolValue());
+ if (mPolygonShapeSpec.hasShadow()) {
+ if (attrs.getAttr("poly_shadow_color").isPresent()) {
+ HiLog.error(LABLE, "自定义poly_shadow_color");
+ mPolygonShapeSpec.setShadowColor(attrs.getAttr("poly_shadow_color").get().getColorValue());
+ } else {
+ HiLog.error(LABLE, "default poly_shadow_color");
+ }
+ }
+ } else {
+ HiLog.error(LABLE, "default poly_shadow");
+ mPolygonShapeSpec.setHasShadow(false);
+ }
+
+ if (attrs.getAttr("poly_border").isPresent()) {
+ HiLog.error(LABLE, "自定义poly_border");
+ mPolygonShapeSpec.setHasBorder(attrs.getAttr("poly_border").get().getBoolValue());
+ if (mPolygonShapeSpec.hasBorder()) {
+ if (attrs.getAttr("poly_border_color").isPresent()) {
+ HiLog.error(LABLE, "自定义poly_border_color");
+ mPolygonShapeSpec.setBorderColor(attrs.getAttr("poly_border_color").get().getColorValue());
+ } else {
+ HiLog.error(LABLE, "default poly_border_color");
+ }
+ }
+ } else {
+ HiLog.error(LABLE, "default poly_border");
+ mPolygonShapeSpec.setHasBorder(false);
+ }
+
+ if (attrs.getAttr("poly_border_width").isPresent()) {
+ HiLog.error(LABLE, "自定义poly_border_width");
+ mPolygonShapeSpec.setBorderWidth(attrs.getAttr("poly_border_width").get().getFloatValue());
+ } else {
+ HiLog.error(LABLE, "default poly_border_width");
+ }
+ }
+ init();
+ setLayoutRefreshedListener(this::onRefreshed);
+
+ }
+
+ @Override
+ public void invalidate() {
+ super.invalidate();
+ addDrawTask(this::onDraw);
+ }
+
+ /**
+ * Init paints and effects
+ */
+ private void init() {
+ HiLog.error(LABLE, "init");
+ mPaint = new Paint();
+ mPaint.setPathEffect(new PathEffect(mPolygonShapeSpec.getCornerRadius()));
+ mBorderPaint = new Paint();
+ mBorderPaint.setStyle(Paint.Style.STROKE_STYLE);
+ mBorderPaint.setPathEffect(new PathEffect(mPolygonShapeSpec.getCornerRadius()));
+
+ if (mPolygonShapeSpec.hasBorder()) {
+ mBorderPaint.setColor(mPolygonShapeSpec.getBorderColor());
+ mBorderPaint.setStrokeWidth(mPolygonShapeSpec.getBorderWidth());
+ }
+
+ if (mPolygonShapeSpec.hasShadow()) {
+ //Shadow on border even if isBordered is false. Better effect and performance that
+ //using shadow on main paint
+ BlurDrawLooper blurDrawLooper = new BlurDrawLooper(mPolygonShapeSpec.getShadowRadius(), mPolygonShapeSpec.getShadowXOffset(),
+ mPolygonShapeSpec.getShadowYOffset(), mPolygonShapeSpec.getShadowColor());
+ mBorderPaint.setBlurDrawLooper(blurDrawLooper);
+
+ }
+
+ mPolygonShape = new RegularPolygonShape();
+ }
+
+ @Override
+ public void onRefreshed(Component component) {
+ HiLog.error(LABLE, "onRefreshed");
+ onMeasure(getWidth(), getHeight());
+
+ if (Math.min(getWidth(), getHeight()) != Math.min(canvasWidth,canvasHeight)) {
+ canvasWidth = getWidth();
+ canvasHeight = getHeight();
+ updatePolygonSize();
+ refreshImage();
+ }
+ }
+
+ /**
+ * Force Override to solve bug on Lollipop
+ *
+ * @param widthMeasureSpec Width Spec Measure
+ * @param heightMeasureSpec Height Spec Measure
+ */
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ HiLog.error(LABLE, "onMeasure");
+ HiLog.error(LABLE, "widthMeasureSpec:"+widthMeasureSpec);
+ HiLog.error(LABLE, "heightMeasureSpec:"+heightMeasureSpec);
+ setComponentSize(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ /**
+ * Draw the polygon form.
+ *
+ * @param canvas main canvas
+ */
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+
+ if (mPixelMap == null || mPixelMap.getImageInfo().size.width == 0 ||
+ mPixelMap.getImageInfo().size.height== 0)
+ {
+ return;
+ }
+
+ switch (mPolygonShapeSpec.getNumVertex()) {
+ case 0: //CIRCLE
+ HiLog.error(LABLE,"onDraw CIRCLE");
+ if (mPolygonShapeSpec.hasShadow() || mPolygonShapeSpec.hasBorder()) {
+ canvas.drawCircle(mPolygonShapeSpec.getCenterX(), mPolygonShapeSpec.getCenterY(),
+ mPolygonShapeSpec.getDiameter() / 2, mBorderPaint);
+ }
+ canvas.drawCircle(mPolygonShapeSpec.getCenterX(), mPolygonShapeSpec.getCenterY(),
+ mPolygonShapeSpec.getDiameter() / 2, mPaint);
+ break;
+ case 1: //REGULAR IMAGE VIEW
+ HiLog.error(LABLE,"onDraw REGULAR");
+ super.setPixelMap(mPixelMap);
+ break;
+ case 2: //SQUARE
+ HiLog.error(LABLE,"onDraw SQUARE");
+ if (mPolygonShapeSpec.hasShadow() || mPolygonShapeSpec.hasBorder()) {
+ canvas.drawRect(new RectFloat(mPolygonShapeSpec.getCenterX() - mPolygonShapeSpec.getDiameter() / 2,
+ mPolygonShapeSpec.getCenterY() - mPolygonShapeSpec.getDiameter() / 2,
+ mPolygonShapeSpec.getCenterX() + mPolygonShapeSpec.getDiameter() / 2,
+ mPolygonShapeSpec.getCenterY() + mPolygonShapeSpec.getDiameter() / 2),
+ mBorderPaint);
+ }
+ canvas.drawRect(new RectFloat(mPolygonShapeSpec.getCenterX() - mPolygonShapeSpec.getDiameter() / 2,
+ mPolygonShapeSpec.getCenterY() - mPolygonShapeSpec.getDiameter() / 2,
+ mPolygonShapeSpec.getCenterX() + mPolygonShapeSpec.getDiameter() / 2,
+ mPolygonShapeSpec.getCenterY() + mPolygonShapeSpec.getDiameter() / 2),
+ mPaint);
+ break;
+ default: //POLYGON
+ HiLog.error(LABLE,"onDraw POLYGON");
+ // HiLog.error(LABLE,"onDraw mPath="+mPath.countPoints());
+ if (mPolygonShapeSpec.hasShadow() || mPolygonShapeSpec.hasBorder())
+ {
+ canvas.drawPath(mPath, mBorderPaint);
+ }
+ canvas.drawPath(mPath, mPaint);
+ }
+
+ }
+
+ /**
+ * Take cares about padding changes.
+ *
+ * @param start start
+ * @param top top
+ * @param end end
+ * @param bottom bottom
+ */
+ @Override
+ public void setPaddingRelative(int start, int top, int end, int bottom) {
+ super.setPaddingRelative(start, top, end, bottom);
+ updatePolygonSize();
+ invalidate();
+ }
+
+ /**
+ * Take cares about padding changes.
+ *
+ * @param left left
+ * @param top top
+ * @param right right
+ * @param bottom bottom
+ */
+ @Override
+ public void setPadding(int left, int top, int right, int bottom) {
+ super.setPadding(left, top, right, bottom);
+ updatePolygonSize(left, top, right, bottom);
+ setComponentPosition(left, top, right, bottom);
+ invalidate();
+ }
+
+ /**
+ * Update image.
+ *
+ * @param pixelMap new image.
+ */
+ @Override
+ public void setPixelMap(PixelMap pixelMap) {
+ mPixelMap = pixelMap;
+ refreshImage();
+ invalidate();
+ }
+
+ @Override
+ public void setPixelMap(int resId) {
+ mPixelMap = getPixelMap(resId);
+ refreshImage();
+ invalidate();
+ }
+
+
+ @Override
+ public void setImageElement(Element element) {
+ super.setImageElement(element);
+ refreshImage();
+ invalidate();
+ }
+
+ /**
+ * 通过资源ID获取位图对象
+ **/
+ private PixelMap getPixelMap(int resId) {
+ InputStream drawableInputStream = null;
+ try {
+ drawableInputStream = getResourceManager().getResource(resId);
+ ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
+ sourceOptions.formatHint = "image/png";
+ ImageSource imageSource = ImageSource.create(drawableInputStream, null);
+ ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
+ decodingOptions.desiredSize = new Size(0, 0);
+ decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
+ decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
+ PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
+ return pixelMap;
+ } catch (Exception e) {
+ e.printStackTrace();
+ HiLog.error(LABLE,"Exception = "+e.getMessage());
+ } finally {
+ try {
+ if (drawableInputStream != null) {
+ drawableInputStream.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ HiLog.error(LABLE,"Exception = "+e.getMessage());
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * 设置颜色过滤器
+ * @param cf 颜色过滤器
+ */
+ public void setColorFilter(ColorFilter cf) {
+ mPaint.setColorFilter(cf);
+ invalidate();
+ }
+
+ /**
+ * 设置颜色过滤器
+ * @param cf 颜色过滤器
+ */
+ public void setColorFilterWithBorder(ColorFilter cf) {
+ mPaint.setColorFilter(cf);
+ mBorderPaint.setColorFilter(cf);
+ invalidate();
+ }
+
+ /**
+ * Rebuild polygon after changes, take cares about padding, border and shadow radius.
+ * Rotate vertices with the variable angle.
+ */
+ private void rebuildPolygon() {
+ HiLog.error(LABLE,"rebuildPolygon");
+ //recalculate new center
+ float borderNeeded = mPolygonShapeSpec.hasBorder() ? mPolygonShapeSpec.getBorderWidth() : 0;
+ float shadowNeeded = mPolygonShapeSpec.hasShadow() ? mPolygonShapeSpec.getShadowRadius() : 0;
+ mPolygonShapeSpec.setCenterX(mPolygonShapeSpec.getDiameter() / 2 + (float) (getPaddingLeft() +
+ getPaddingRight()) / 2 + borderNeeded + shadowNeeded);
+ mPolygonShapeSpec.setCenterY(mPolygonShapeSpec.getDiameter() / 2 + (float) (getPaddingTop() +
+ getPaddingBottom()) / 2 + borderNeeded + shadowNeeded);
+
+ HiLog.error(LABLE,"CenterX:"+mPolygonShapeSpec.getCenterX()+",CenterY:"+mPolygonShapeSpec.getCenterY());
+ if (mPolygonShapeSpec.getNumVertex() < 3)
+ return;
+
+ HiLog.error(LABLE,"mPolygonShapeSpec:"+mPolygonShapeSpec.getNumVertex());
+ mPath = mPolygonShape.getPolygonPath(mPolygonShapeSpec);
+ }
+
+ /**
+ * Update polygon size with unspecified padding.
+ */
+ private void updatePolygonSize() {
+ updatePolygonSize(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom());
+ }
+
+ /**
+ * Update polygon with new padding.
+ *
+ * @param l Left padding.
+ * @param t Top padding.
+ * @param r Right padding.
+ * @param b Bottom padding.
+ */
+ private void updatePolygonSize(int l, int t, int r, int b) {
+ HiLog.error(LABLE,"updatePolygonSize");
+ HiLog.error(LABLE,"l:"+l+",t:"+t+",r:"+r+",b:"+b);
+ if (mPolygonShapeSpec == null || canvasWidth == 0 || canvasHeight == 0)
+ return;
+
+ float borderPadding = mPolygonShapeSpec.hasBorder() ? mPolygonShapeSpec.getBorderWidth() : 0f;
+ float shadowPadding = mPolygonShapeSpec.hasShadow() ? mPolygonShapeSpec.getShadowRadius() : 0f;
+ float xPadding = (l + r + (borderPadding * 2) + (shadowPadding * 2));
+ float yPadding = (t + b + (borderPadding * 2) + (shadowPadding * 2));
+ float diameter = Math.min((float) canvasWidth - xPadding, (float) canvasHeight - yPadding);
+ //if the size is changed we need to rebuild the polygon
+ HiLog.error(LABLE,"borderPadding:"+borderPadding);
+ HiLog.error(LABLE,"shadowPadding:"+shadowPadding);
+ HiLog.error(LABLE,"xPadding:"+xPadding);
+ HiLog.error(LABLE,"yPadding:"+yPadding);
+ HiLog.error(LABLE,"diameter:"+diameter);
+ HiLog.error(LABLE,"mPolygonShapeSpec.getDiameter():"+mPolygonShapeSpec.getDiameter());
+ if (diameter != mPolygonShapeSpec.getDiameter()) {
+ mPolygonShapeSpec.setDiameter(diameter);
+ rebuildPolygon();
+ }
+ }
+
+ /**
+ * @param polygonShape set new shape
+ */
+ public void setPolygonShape(PolygonShape polygonShape) {
+ mPolygonShape = polygonShape;
+ updatePolygonSize();
+ invalidate();
+ }
+
+ /**
+ * @return get current shape
+ */
+ public PolygonShape getPolygonShape() {
+ return mPolygonShape;
+ }
+
+ /**
+ * @return get current shape spec
+ */
+ public PolygonShapeSpec getPolygonShapeSpec() {
+ return mPolygonShapeSpec;
+ }
+
+ /**
+ * @param spec set shape spec
+ */
+ public void setPolygonShapeSpec(PolygonShapeSpec spec) {
+ this.mPolygonShapeSpec = spec;
+ }
+
+ /**
+ * Returns the rotate angle.
+ *
+ * @return angle in degrees.
+ */
+ public float getRotationAngle() {
+ return mPolygonShapeSpec.getRotation();
+ }
+
+ /**
+ * Set new rotate angle and updates polygon form.
+ *
+ * @param mAngle angle in degrees.
+ */
+ public void setRotationAngle(float mAngle) {
+ mPolygonShapeSpec.setRotation(mAngle);
+ updatePolygonSize();
+ invalidate();
+ }
+
+ /**
+ * Returns the vertex number.
+ *
+ * @return vertex number
+ */
+ public int getVertices() {
+ return mPolygonShapeSpec.getNumVertex();
+ }
+
+ /**
+ * Sets the new vertex number and updates polygon form.
+ *
+ * @param numVertices new number of vertices
+ */
+ public void setVertices(int numVertices) {
+ mPolygonShapeSpec.setNumVertex(numVertices);
+ updatePolygonSize();
+ invalidate();
+ }
+
+ /**
+ * Indicates if it's bordered.
+ *
+ * @return boolean
+ */
+ public boolean isBordered() {
+ return mPolygonShapeSpec.hasBorder();
+ }
+
+ /**
+ * Enables or disables the border option.
+ *
+ * @param bordered if it's bordered
+ */
+ public void setBorder(boolean bordered) {
+ mPolygonShapeSpec.setHasBorder(bordered);
+ updateBorderSpecs();
+ }
+
+ /**
+ * Sets new border width.
+ *
+ * @param borderWidth new width.
+ */
+ public void setBorderWidth(float borderWidth) {
+ mPolygonShapeSpec.setBorderWidth(borderWidth);
+ updateBorderSpecs();
+ }
+
+ /**
+ * Sets new border width and update polygon size.
+ */
+ private void updateBorderSpecs() {
+ if (mPolygonShapeSpec.hasBorder()) {
+ mBorderPaint.setStrokeWidth(mPolygonShapeSpec.getBorderWidth());
+ mBorderPaint.setColor(mPolygonShapeSpec.getBorderColor());
+ } else {
+ mBorderPaint.setStrokeWidth(0);
+ mBorderPaint.setColor(Color.BLACK);
+ }
+ updatePolygonSize();
+ invalidate();
+ }
+
+ /**
+ * Sets new border color.
+ *
+ * @param borderColor Color class var.
+ */
+ public void setBorderColor(Color borderColor) {
+ mPolygonShapeSpec.setBorderColor(borderColor);
+ mBorderPaint.setColor(borderColor);
+ invalidate();
+ }
+
+ /**
+ * Sets new border color
+ *
+ * @param resourceBorderColor Resource xml color.
+ */
+ public void setBorderColorResource(int resourceBorderColor) {
+ try {
+ Color color = new Color(getResourceManager().getElement(resourceBorderColor).getColor());
+ setBorderColor(color);
+ mBorderPaint.setColor(color);
+ invalidate();
+ } catch (IOException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ } catch (NotExistException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ } catch (WrongTypeException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ }
+ }
+
+ /**
+ * 添加边框属性
+ * @param borderWidth 边框宽度
+ * @param borderColor 边框颜色
+ */
+ public void addBorder(float borderWidth, Color borderColor) {
+ mPolygonShapeSpec.setHasBorder(true);
+ mPolygonShapeSpec.setBorderWidth(borderWidth);
+ mPolygonShapeSpec.setBorderColor(borderColor);
+ updateBorderSpecs();
+ }
+
+ /**
+ * 设置边框
+ * @param borderWidth 边框宽度
+ * @param resourceBorderColor 边框颜色ID
+ */
+ public void addBorderResource(float borderWidth, int resourceBorderColor) {
+ try {
+ addBorder(borderWidth, new Color(getResourceManager().getElement(resourceBorderColor).getColor()));
+ } catch (IOException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ } catch (NotExistException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ } catch (WrongTypeException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ }
+ }
+
+ /**
+ * 设置边框
+ * @param borderWidth 边框宽度
+ * @param color 边框颜色
+ */
+ public void addBorderResource(float borderWidth, Color color) {
+ addBorder(borderWidth, color);
+
+ }
+
+ /**
+ * Sets new radius for corners and updates view.
+ *
+ * @param cornerRadius new corner radius
+ */
+ public void setCornerRadius(float cornerRadius) {
+ mPolygonShapeSpec.setCornerRadius(cornerRadius);
+ mBorderPaint.setPathEffect(new PathEffect(cornerRadius));
+ mPaint.setPathEffect(new PathEffect(cornerRadius));
+ invalidate();
+ }
+
+ /**
+ * Adds a default shadow
+ */
+ public void addShadow() {
+ startShadow();
+ }
+
+ /**
+ * Adds a specific shadow.
+ *
+ * @param radius shadow blur size.
+ * @param offsetX negative value moves shadow to left and positive to right.
+ * @param offsetY negative value moves shadow down and positive towards up.
+ * @param color shadow color
+ */
+ public void addShadow(float radius, float offsetX, float offsetY, int color) {
+ mPolygonShapeSpec.setShadowRadius(radius);
+ mPolygonShapeSpec.setShadowXOffset(offsetX);
+ mPolygonShapeSpec.setShadowYOffset(offsetY);
+ mPolygonShapeSpec.setShadowColor(new Color(color));
+ startShadow();
+ }
+
+ /**
+ * 添加阴影
+ * @param radius 半径
+ * @param offsetX X偏移量
+ * @param offsetY Y偏移量
+ * @param colorId 颜色ID
+ */
+ public void addShadowResource(float radius, float offsetX, float offsetY, int colorId) {
+ try {
+ addShadow(radius, offsetX, offsetY, getResourceManager().getElement(colorId).getColor());
+ } catch (IOException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ } catch (NotExistException e) {
+ HiLog.error(LABLE,"Do not find colorId:"+e.getMessage());
+ } catch (WrongTypeException e) {
+ HiLog.error(LABLE,"Do not find colorId"+e.getMessage());
+ }
+ }
+
+ /**
+ * 添加阴影
+ * @param radius 半径
+ * @param offsetX X偏移量
+ * @param offsetY Y偏移量
+ * @param color 颜色
+ */
+ public void addShadowResource(float radius, float offsetX, float offsetY, Color color) {
+ addShadow(radius, offsetX, offsetY, color.getValue());
+ }
+
+ /**
+ * 设置画笔阴影
+ */
+ private void startShadow() {
+ mPolygonShapeSpec.setHasShadow(true);
+ BlurDrawLooper blurDrawLooper = new BlurDrawLooper(mPolygonShapeSpec.getShadowRadius(), mPolygonShapeSpec.getShadowXOffset(),
+ mPolygonShapeSpec.getShadowYOffset(), mPolygonShapeSpec.getShadowColor());
+ mBorderPaint.setBlurDrawLooper(blurDrawLooper);
+ updatePolygonSize();
+ invalidate();
+ }
+
+ /**
+ * Removes shadow
+ */
+ public void clearShadow() {
+ if (!mPolygonShapeSpec.hasShadow())
+ return;
+
+ mPolygonShapeSpec.setHasShadow(false);
+ mBorderPaint.clearBlurDrawLooper();
+ updatePolygonSize();
+ invalidate();
+ }
+
+ /**
+ * Refresh image with new canvas size or new image.
+ */
+ private void refreshImage() {
+ HiLog.error(LABLE,"refreshImage");
+ HiLog.error(LABLE,"image size:width="+mPixelMap.getImageInfo().size.width);
+ HiLog.error(LABLE,"image size:height="+mPixelMap.getImageInfo().size.height);
+ int canvasSize = Math.min(canvasWidth, canvasHeight);
+ HiLog.error(LABLE,"canvasSize="+canvasSize);
+ if (canvasSize > 0 && mPixelMap != null) {
+ //Preserve image ratio if it is not square
+ PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
+ Size size = new Size(canvasSize, canvasSize);
+ options.size = size;
+ options.pixelFormat = PixelFormat.ARGB_8888;
+// options.scaleMode = ohos.media.image.common.ScaleMode.FIT_TARGET_SIZE;
+ PixelMap pixelMap = PixelMap.create(mPixelMap,options);
+ PixelMapHolder holder = new PixelMapHolder(pixelMap);
+ PixelMapShader shader = new PixelMapShader(holder, Shader.TileMode.CLAMP_TILEMODE, Shader.TileMode.CLAMP_TILEMODE);
+ mPaint.setShader(shader, Paint.ShaderType.PIXELMAP_SHADER);
+
+
+// HiLog.info(LABLE, "initializePixelMap");
+// PixelMapHolder pixelMapHolder = null;
+// if (mPixelMap != null) {
+// pixelMapHolder = new PixelMapHolder(mPixelMap);
+// updateShaderMatrix();
+// invalidate();//重新检验该组件
+// } else {
+// HiLog.info(LABLE, "Log_mPixelMapNULL");
+// pixelMapHolder = null;
+// }
+// PixelMapShader bitmapShader = new PixelMapShader(pixelMapHolder, Shader.TileMode.CLAMP_TILEMODE, Shader.TileMode.CLAMP_TILEMODE);
+// bitmapShader.setShaderMatrix(mShaderMatrix);
+// mPaint.setShader(bitmapShader, Paint.ShaderType.PIXELMAP_SHADER);
+ }
+ }
+
+ /**
+ * 这个函数为获取pixelMapShader的Matrix参数,设置最小缩放比例,平移参数。
+ * 作用:保证图片损失度最小和始终绘制图片正中央的那部分
+ */
+ private void updateShaderMatrix() {
+ // mPixelMap = getPixelMap();
+ if (mPixelMap == null) {
+ HiLog.info(LABLE, "Log_mPixelMapNULL");
+ return;
+ }
+
+ float scale;
+ float dx = 0;
+ float dy = 0;
+
+ mShaderMatrix.setMatrix(null);
+
+ int pixelMapHeight = mPixelMap.getImageInfo().size.height;
+ int pixelMapWidth = mPixelMap.getImageInfo().size.height;
+
+ if (pixelMapWidth * canvasHeight > canvasWidth * pixelMapHeight) {
+ scale = canvasHeight / (float) pixelMapHeight;
+ dx = (canvasWidth - pixelMapWidth * scale) * 0.5f;
+ } else {
+ scale = canvasWidth / (float) pixelMapWidth;
+ dy = (canvasHeight - pixelMapHeight * scale) * 0.5f;
+ }
+
+ mShaderMatrix.setScale(scale, scale);
+ mShaderMatrix.postTranslate((int) (dx + 0.5f) + mPolygonShapeSpec.getCenterX()-mPolygonShapeSpec.getDiameter()/2, (int) (dy + 0.5f) + mPolygonShapeSpec.getCenterY()-mPolygonShapeSpec.getDiameter()/2);
+ HiLog.info(LABLE, "Log_mPixelMapEND");
+// mRebuildShader = true;
+ }
+
+
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/view/util/GeometryUtil.java b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/view/util/GeometryUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..39e2ec1cecf663b673136ad981998f1cf78f2e2e
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/java/com/isoftstone/polygonimageview/view/util/GeometryUtil.java
@@ -0,0 +1,62 @@
+package com.isoftstone.polygonimageview.view.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Geometry Util
+ */
+public class GeometryUtil {
+
+ /**
+ * Intersection between line, determined for two points, and a circle with radius x
+ * @param pointA line point a
+ * @param pointB line point b
+ * @param center point center circle
+ * @param radius circle radius
+ * @return intersection points
+ */
+ public static List getCircleLineIntersectionPoint(Point pointA, Point pointB, Point center, double radius) {
+ double baX = pointB.x - pointA.x;
+ double baY = pointB.y - pointA.y;
+ double caX = center.x - pointA.x;
+ double caY = center.y - pointA.y;
+
+ double a = baX * baX + baY * baY;
+ double bBy2 = baX * caX + baY * caY;
+ double c = caX * caX + caY * caY - radius * radius;
+
+ double pBy2 = bBy2 / a;
+ double q = c / a;
+
+ double disc = pBy2 * pBy2 - q;
+ if (disc < 0) {
+ return Collections.emptyList();
+ }
+
+ double tmpSqrt = Math.sqrt(disc);
+ double abScalingFactor1 = -pBy2 + tmpSqrt;
+ double abScalingFactor2 = -pBy2 - tmpSqrt;
+
+ Point p1 = new Point(pointA.x - baX * abScalingFactor1, pointA.y
+ - baY * abScalingFactor1);
+ if (disc == 0) {
+ return Collections.singletonList(p1);
+ }
+ Point p2 = new Point(pointA.x - baX * abScalingFactor2, pointA.y
+ - baY * abScalingFactor2);
+ return Arrays.asList(p1, p2);
+ }
+
+ public static class Point {
+ public double x, y;
+
+ public Point(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
+
+
+ }
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/resources/base/element/string.json b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..6c0ee41924e709c25fb9b7bac00517933672476f
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/polygonimageview/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Polygonimageview"
+ }
+ ]
+}
diff --git a/007.PolygonImageView_OpenHarmony_master/code/settings.gradle b/007.PolygonImageView_OpenHarmony_master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..6e20514c8eb5de449978b33d462130ec178dbe22
--- /dev/null
+++ b/007.PolygonImageView_OpenHarmony_master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':polygonimageview'
diff --git "a/007.PolygonImageView_OpenHarmony_master/doc/007.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PolygonImageView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/007.PolygonImageView_OpenHarmony_master/doc/007.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PolygonImageView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..0c5761cfc6c95fc75c71b386f0e68ded84cef1cf
Binary files /dev/null and "b/007.PolygonImageView_OpenHarmony_master/doc/007.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PolygonImageView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.gitignore b/008.LoadingDrawable_OpenHarmony_master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/.gitignore b/008.LoadingDrawable_OpenHarmony_master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/compiler.xml b/008.LoadingDrawable_OpenHarmony_master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/gradle.xml b/008.LoadingDrawable_OpenHarmony_master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e4d6449e7a9972df0a0e10be73fe187736cb9064
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/jarRepositories.xml b/008.LoadingDrawable_OpenHarmony_master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/misc.xml b/008.LoadingDrawable_OpenHarmony_master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-1235739606.json b/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-1235739606.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-1235739606.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-937192615.json b/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-937192615.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/phone/phoneSettingConfig_-937192615.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/previewConfig.json b/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..a112d96336571e61a3e545451ddc9f2e2c7f28a0
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/previewer/previewConfig.json
@@ -0,0 +1,12 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\PCFile\\PCFile\\svn\\010.LoadingDrawable\\LoadingView_HarmonyOS\\entry": [
+ "phone"
+ ],
+ "D:\\PCFile\\PCFile\\thirdcomponent\\thirdcomponent\\01.LoadingDrawable\\LoadingView_HarmonyOS\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/.idea/vcs.xml b/008.LoadingDrawable_OpenHarmony_master/code/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2bdec2d71b6a5ce4ae49efc37516809c50e4d5e
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/build.gradle b/008.LoadingDrawable_OpenHarmony_master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..55ee9133b112de29625c7bbc52be1caad80bdd5f
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/.gitignore b/008.LoadingDrawable_OpenHarmony_master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/build.gradle b/008.LoadingDrawable_OpenHarmony_master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1516e0540a2da7948d4284747ec3d22614490cf6
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ compile project(path: ':loadingview')
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/loadingview-release.har b/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/loadingview-release.har
new file mode 100644
index 0000000000000000000000000000000000000000..1b888e0c5c562241b4da0126316c59727a45e2b8
Binary files /dev/null and b/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/loadingview-release.har differ
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/loadingview.har b/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/loadingview.har
new file mode 100644
index 0000000000000000000000000000000000000000..1db051b92503ac6f841256be29389ef930ed553c
Binary files /dev/null and b/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/loadingview.har differ
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/precentpositionlayout.har b/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/precentpositionlayout.har
new file mode 100644
index 0000000000000000000000000000000000000000..c697b301fa575a2756b6f3eb4336ac4e22660a29
Binary files /dev/null and b/008.LoadingDrawable_OpenHarmony_master/code/entry/libs/precentpositionlayout.har differ
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/config.json b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e7a909f201585a02cbd8a3903b27540512bd82e
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.loadingview_harmonyos",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.loadingview_harmonyos",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.isoftstone.loadingview_harmonyos.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/MainAbility.java b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..62c46fc9f48d83f37480d6437a300834be4e0d39
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/MainAbility.java
@@ -0,0 +1,13 @@
+package com.isoftstone.loadingview_harmonyos;
+
+import com.isoftstone.loadingview_harmonyos.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/MyApplication.java b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..9888b7c7334a2b130eb049da77df4358efd0f54d
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/MyApplication.java
@@ -0,0 +1,10 @@
+package com.isoftstone.loadingview_harmonyos;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/slice/MainAbilitySlice.java b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff3ce77f418a9986c1f8c388885a3a9233fc2cf5
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/java/com/isoftstone/loadingview_harmonyos/slice/MainAbilitySlice.java
@@ -0,0 +1,46 @@
+package com.isoftstone.loadingview_harmonyos.slice;
+
+import com.isoftstone.loadingview.LoadingView;
+import com.isoftstone.loadingview_harmonyos.ResourceTable;
+import com.isoftstone.precentpositionlayout.PrecentPositionLayout;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+
+public class MainAbilitySlice extends AbilitySlice {
+ PrecentPositionLayout precentPositionLayout;
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ LoadingView loadingView1 = (LoadingView)findComponentById(ResourceTable.Id_text_water);
+ loadingView1.SetType(LoadingView.LoadingViewType.WATER);
+ loadingView1.addDrawTask(loadingView1);
+
+ LoadingView loadingView2 = (LoadingView)findComponentById(ResourceTable.Id_text_ballon);
+ loadingView2.SetType(LoadingView.LoadingViewType.BALLOON);
+ loadingView2.addDrawTask(loadingView2);
+
+ LoadingView loadingView3 = (LoadingView)findComponentById(ResourceTable.Id_text_fish);
+ loadingView3.SetType(LoadingView.LoadingViewType.FISH);
+ loadingView3.addDrawTask(loadingView3);
+
+ LoadingView loadingView4 = (LoadingView)findComponentById(ResourceTable.Id_text_circle);
+ loadingView4.SetType(LoadingView.LoadingViewType.CIRCLE);
+ loadingView4.addDrawTask(loadingView4);
+
+ PrecentPositionLayout precentPositionLayout
+ = (PrecentPositionLayout)findComponentById(ResourceTable.Id_layout_main);
+ precentPositionLayout.AutoSize();
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/element/string.json b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..aadefd79f98d1df81bff13328ecd5f0606b71c31
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "LoadingView_HarmonyOS"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_text.xml b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_text.xml
new file mode 100644
index 0000000000000000000000000000000000000000..632ac8886e0fb78f2f12193f08f098768ed8c752
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/graphic/background_text.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/layout/ability_main.xml b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ff2cb1bf34bea5e82064fd531f56001426812d35
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/media/icon.png b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/entry/src/test/java/com/isoftstone/loadingview_harmonyos/ExampleTest.java b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/test/java/com/isoftstone/loadingview_harmonyos/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f45688e807ac8ae4ff4560650039a0b54e537c2
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/entry/src/test/java/com/isoftstone/loadingview_harmonyos/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.isoftstone.loadingview_harmonyos;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/gradle.properties b/008.LoadingDrawable_OpenHarmony_master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.jar b/008.LoadingDrawable_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/008.LoadingDrawable_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.properties b/008.LoadingDrawable_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/gradlew b/008.LoadingDrawable_OpenHarmony_master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/gradlew.bat b/008.LoadingDrawable_OpenHarmony_master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/.gitignore b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/build.gradle b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/config.json b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..fa0ac20b20cdc6980f07e6ce9feb2ac7e083567d
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.loadingview_harmonyos",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.loadingview",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "loadingview",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/DensityUtil.java b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/DensityUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..a57af0600a6c2b28be0e7be9827945562e5d6ed5
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/DensityUtil.java
@@ -0,0 +1,15 @@
+package com.isoftstone.loadingview;
+
+import ohos.app.Context;
+
+
+import ohos.app.Context;
+
+public class DensityUtil {
+
+ public static float dip2px(Context context, float dpValue) {
+ //float scale = context.getResources().getDisplayMetrics().density;
+ //return dpValue * scale;
+ return dpValue * 6.5f;
+ }
+}
\ No newline at end of file
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRander.java b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRander.java
new file mode 100644
index 0000000000000000000000000000000000000000..9051144c5919a54542fd9ba6163cd1b349fcdca0
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRander.java
@@ -0,0 +1,26 @@
+package com.isoftstone.loadingview;
+import ohos.agp.render.Canvas;
+import ohos.agp.utils.Rect;
+
+
+public class LoadingRander {
+
+ protected float mProgress;
+ protected float mWidth;
+ protected float mHeight;
+ protected float mTextSize;
+
+ public LoadingRander() {
+
+ }
+
+ // 设置进度
+ public void setProgess(float progress) {
+ mProgress = progress;
+ }
+
+ // 绘制
+ protected void draw(Canvas canvas, Rect bounds) {
+ return;
+ }
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderBalloon.java b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderBalloon.java
new file mode 100644
index 0000000000000000000000000000000000000000..975d847fdf6b88733ecce83ce1504fa098a10908
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderBalloon.java
@@ -0,0 +1,270 @@
+package com.isoftstone.loadingview;
+
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.render.Path;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.Point;
+import ohos.agp.utils.Rect;
+import ohos.agp.utils.RectFloat;
+import ohos.app.Context;
+
+public class LoadingRanderBalloon extends LoadingRander {
+ private static final String PERCENT_SIGN = "%";
+
+ //private static final Interpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
+
+ private static final float START_INHALE_DURATION_OFFSET = 0.4f;
+
+ private static final float DEFAULT_WIDTH = 200.0f;
+ private static final float DEFAULT_HEIGHT = 150.0f;
+ private static final float DEFAULT_STROKE_WIDTH = 2.0f;
+ private static final float DEFAULT_GAS_TUBE_WIDTH = 48;
+ private static final float DEFAULT_GAS_TUBE_HEIGHT = 20;
+ private static final float DEFAULT_CANNULA_WIDTH = 13;
+ private static final float DEFAULT_CANNULA_HEIGHT = 37;
+ private static final float DEFAULT_CANNULA_OFFSET_Y = 3;
+ private static final float DEFAULT_CANNULA_MAX_OFFSET_Y = 15;
+ private static final float DEFAULT_PIPE_BODY_WIDTH = 16;
+ private static final float DEFAULT_PIPE_BODY_HEIGHT = 36;
+ private static final float DEFAULT_BALLOON_WIDTH = 38;
+ private static final float DEFAULT_BALLOON_HEIGHT = 48;
+ private static final float DEFAULT_RECT_CORNER_RADIUS = 2;
+
+ private static final int DEFAULT_BALLOON_COLOR = Color.getIntColor("#ffF3C211");
+ private static final int DEFAULT_GAS_TUBE_COLOR = Color.getIntColor("#ff174469");
+ private static final int DEFAULT_PIPE_BODY_COLOR = Color.getIntColor("#aa2369B1");
+ private static final int DEFAULT_CANNULA_COLOR = Color.getIntColor("#ff174469");
+
+ private static final float DEFAULT_TEXT_SIZE = 7.0f;
+
+ private static final long ANIMATION_DURATION = 3333;
+
+ private final Paint mPaint = new Paint();
+ private final RectFloat mCurrentBounds = new RectFloat();
+ private final RectFloat mGasTubeBounds = new RectFloat();
+ private final RectFloat mPipeBodyBounds = new RectFloat();
+ private final RectFloat mCannulaBounds = new RectFloat();
+ private final RectFloat mBalloonBounds = new RectFloat();
+
+ private final Rect mProgressBounds = new Rect();
+
+ private float mTextSize;
+
+ private String mProgressText;
+
+ private float mGasTubeWidth;
+ private float mGasTubeHeight;
+ private float mCannulaWidth;
+ private float mCannulaHeight;
+ private float mCannulaMaxOffsetY;
+ private float mCannulaOffsetY;
+ private float mPipeBodyWidth;
+ private float mPipeBodyHeight;
+ private float mBalloonWidth;
+ private float mBalloonHeight;
+ private float mRectCornerRadius;
+ private float mStrokeWidth;
+
+ private Color mBalloonColor;
+ private Color mGasTubeColor;
+ private Color mCannulaColor;
+ private Color mPipeBodyColor;
+
+ public LoadingRanderBalloon() {
+ super();
+ init();
+ setupPaint();
+ }
+
+ private void init() {
+ mTextSize = DensityUtil.dip2px(null, DEFAULT_TEXT_SIZE);
+
+ mWidth = DensityUtil.dip2px(null, DEFAULT_WIDTH);
+ mHeight = DensityUtil.dip2px(null, DEFAULT_HEIGHT);
+ mStrokeWidth = DensityUtil.dip2px(null, DEFAULT_STROKE_WIDTH);
+
+ mGasTubeWidth = DensityUtil.dip2px(null, DEFAULT_GAS_TUBE_WIDTH);
+ mGasTubeHeight = DensityUtil.dip2px(null, DEFAULT_GAS_TUBE_HEIGHT);
+ mCannulaWidth = DensityUtil.dip2px(null, DEFAULT_CANNULA_WIDTH);
+ mCannulaHeight = DensityUtil.dip2px(null, DEFAULT_CANNULA_HEIGHT);
+ mCannulaOffsetY = DensityUtil.dip2px(null, DEFAULT_CANNULA_OFFSET_Y);
+ mCannulaMaxOffsetY = DensityUtil.dip2px(null, DEFAULT_CANNULA_MAX_OFFSET_Y);
+ mPipeBodyWidth = DensityUtil.dip2px(null, DEFAULT_PIPE_BODY_WIDTH);
+ mPipeBodyHeight = DensityUtil.dip2px(null, DEFAULT_PIPE_BODY_HEIGHT);
+ mBalloonWidth = DensityUtil.dip2px(null, DEFAULT_BALLOON_WIDTH);
+ mBalloonHeight = DensityUtil.dip2px(null, DEFAULT_BALLOON_HEIGHT);
+ mRectCornerRadius = DensityUtil.dip2px(null, DEFAULT_RECT_CORNER_RADIUS);
+
+ mBalloonColor = new Color(DEFAULT_BALLOON_COLOR);
+ mGasTubeColor = new Color(DEFAULT_GAS_TUBE_COLOR);
+ mCannulaColor = new Color(DEFAULT_CANNULA_COLOR);
+ mPipeBodyColor = new Color(DEFAULT_PIPE_BODY_COLOR);
+
+ mProgressText = 10 + PERCENT_SIGN;
+
+ //mDuration = ANIMATION_DURATION;
+ }
+
+ private void setupPaint() {
+ mPaint.setAntiAlias(true);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ }
+
+ @Override
+ protected void draw(Canvas canvas, Rect bounds) {
+ int saveCount = canvas.save();
+
+ RectFloat arcBounds = mCurrentBounds;
+ arcBounds.modify(bounds);
+
+ computeRender(mProgress);
+
+ //draw draw gas tube
+ mPaint.setColor(mGasTubeColor);
+ mPaint.setStyle(Paint.Style.STROKE_STYLE);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ canvas.drawPath(createGasTubePath(mGasTubeBounds), mPaint);
+
+ //draw balloon
+ mPaint.setColor(mBalloonColor);
+ mPaint.setStyle(Paint.Style.FILLANDSTROKE_STYLE);
+ canvas.drawPath(createBalloonPath(mBalloonBounds, mProgress), mPaint);
+
+ //draw progress
+ mPaint.setColor(mGasTubeColor);
+ mPaint.setTextSize((int) mTextSize);
+ mPaint.setStrokeWidth(mStrokeWidth / 5.0f);
+ canvas.drawText(mPaint, mProgressText, arcBounds.getCenter().getPointX() - mProgressBounds.getWidth() / 2.0f,
+ mGasTubeBounds.getCenter().getPointY() + mProgressBounds.getHeight() / 2.0f);
+
+ //draw cannula
+ mPaint.setColor(mCannulaColor);
+ mPaint.setStyle(Paint.Style.STROKE_STYLE);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ canvas.drawPath(createCannulaHeadPath(mCannulaBounds), mPaint);
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
+ canvas.drawPath(createCannulaBottomPath(mCannulaBounds), mPaint);
+
+ //draw pipe body
+ mPaint.setColor(mPipeBodyColor);
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
+ canvas.drawRoundRect(mPipeBodyBounds, mRectCornerRadius, mRectCornerRadius, mPaint);
+
+ canvas.restoreToCount(saveCount);
+ }
+
+ protected void computeRender(float renderProgress) {
+ RectFloat arcBounds = mCurrentBounds;
+ //compute gas tube bounds
+ mGasTubeBounds.modify(arcBounds.getCenter().getPointX() - mGasTubeWidth / 2.0f, arcBounds.getCenter().getPointY(),
+ arcBounds.getCenter().getPointX() + mGasTubeWidth / 2.0f, arcBounds.getCenter().getPointY() + mGasTubeHeight);
+ //compute pipe body bounds
+ mPipeBodyBounds.modify(arcBounds.getCenter().getPointX() + mGasTubeWidth / 2.0f - mPipeBodyWidth / 2.0f, arcBounds.getCenter().getPointY() - mPipeBodyHeight,
+ arcBounds.getCenter().getPointX() + mGasTubeWidth / 2.0f + mPipeBodyWidth / 2.0f, arcBounds.getCenter().getPointY());
+ //compute cannula bounds
+ mCannulaBounds.modify(arcBounds.getCenter().getPointX() + mGasTubeWidth / 2.0f - mCannulaWidth / 2.0f, arcBounds.getCenter().getPointY() - mCannulaHeight - mCannulaOffsetY,
+ arcBounds.getCenter().getPointX() + mGasTubeWidth / 2.0f + mCannulaWidth / 2.0f, arcBounds.getCenter().getPointY() - mCannulaOffsetY);
+ //compute balloon bounds
+ float insetX = mBalloonWidth * 0.333f * (1 - mProgress);
+ float insetY = mBalloonHeight * 0.667f * (1 - mProgress);
+ mBalloonBounds.modify(arcBounds.getCenter().getPointX() - mGasTubeWidth / 2.0f - mBalloonWidth / 2.0f + insetX, arcBounds.getCenter().getPointY() - mBalloonHeight + insetY,
+ arcBounds.getCenter().getPointX() - mGasTubeWidth / 2.0f + mBalloonWidth / 2.0f - insetX, arcBounds.getCenter().getPointY());
+
+
+ mCannulaBounds.modify(mCannulaBounds.left, mCannulaBounds.top, mCannulaBounds.right,
+ mCannulaBounds.bottom -mCannulaMaxOffsetY * renderProgress / START_INHALE_DURATION_OFFSET);
+
+
+ //mProgress = 0.0f;
+ mProgressText = (int)(mProgress * 100) + PERCENT_SIGN;
+
+ //mPaint.setTextSize(mTextSize);
+ //mPaint.getTextBounds(mProgressText, 0, mProgressText.length(), mProgressBounds);
+
+ }
+
+ private int adjustProgress(int progress) {
+ progress = progress / 10 * 10;
+ progress = 100 - progress + 10;
+ if (progress > 100) {
+ progress = 100;
+ }
+
+ return progress;
+ }
+
+ private Path createGasTubePath(RectFloat gasTubeRect) {
+ Path path = new Path();
+ path.moveTo(gasTubeRect.left, gasTubeRect.top);
+ path.lineTo(gasTubeRect.left, gasTubeRect.bottom);
+ path.lineTo(gasTubeRect.right, gasTubeRect.bottom);
+ path.lineTo(gasTubeRect.right, gasTubeRect.top);
+ return path;
+ }
+
+ private Path createCannulaHeadPath(RectFloat cannulaRect) {
+ Path path = new Path();
+ path.moveTo(cannulaRect.left, cannulaRect.top);
+ path.lineTo(cannulaRect.right, cannulaRect.top);
+ path.moveTo(cannulaRect.getCenter().getPointX(), cannulaRect.top);
+ path.lineTo(cannulaRect.getCenter().getPointX(), cannulaRect.bottom - 0.833f * cannulaRect.getWidth());
+ return path;
+ }
+
+ private Path createCannulaBottomPath(RectFloat cannulaRect) {
+ RectFloat cannulaHeadRect = new RectFloat(cannulaRect.left, cannulaRect.bottom - 0.833f * cannulaRect.getWidth(),
+ cannulaRect.right, cannulaRect.bottom);
+
+ Path path = new Path();
+ path.addRoundRect(cannulaHeadRect, mRectCornerRadius, mRectCornerRadius, Path.Direction.COUNTER_CLOCK_WISE);
+ return path;
+ }
+
+ /**
+ * Coordinates are approximate, you have better cooperate with the designer's design draft
+ */
+ private Path createBalloonPath(RectFloat balloonRect, float progress) {
+
+ Path path = new Path();
+ path.moveTo(balloonRect.getCenter().getPointX(), balloonRect.bottom);
+
+ float progressWidth = balloonRect.getWidth() * progress;
+ float progressHeight = balloonRect.getHeight() * progress;
+ //draw left half
+ float leftIncrementX1 = progressWidth * -0.48f;
+ float leftIncrementY1 = progressHeight * 0.75f;
+ float leftIncrementX2 = progressWidth * -0.03f;
+ float leftIncrementY2 = progressHeight * -1.6f;
+ float leftIncrementX3 = progressWidth * 0.9f;
+ float leftIncrementY3 = progressHeight * -1.0f;
+
+ path.cubicTo(new Point(balloonRect.left + balloonRect.getWidth() * 0.25f + leftIncrementX1, balloonRect.getCenter().getPointY() - balloonRect.getHeight() * 0.4f + leftIncrementY1),
+ new Point(balloonRect.left - balloonRect.getWidth() * 0.20f + leftIncrementX2, balloonRect.getCenter().getPointY() + balloonRect.getHeight() * 1.15f + leftIncrementY2),
+ new Point(balloonRect.left - balloonRect.getWidth() * 0.4f + leftIncrementX3, balloonRect.bottom + leftIncrementY3));
+
+// the results of the left final transformation
+// path.cubicTo(balloonRect.left - balloonRect.width() * 0.13f, balloonRect.centerY() + balloonRect.height() * 0.35f,
+// balloonRect.left - balloonRect.width() * 0.23f, balloonRect.centerY() - balloonRect.height() * 0.45f,
+// balloonRect.left + balloonRect.width() * 0.5f, balloonRect.bottom - balloonRect.height());
+
+ //draw right half
+ float rightIncrementX1 = progressWidth * 1.51f;
+ float rightIncrementY1 = progressHeight * -0.05f;
+ float rightIncrementX2 = progressWidth * 0.03f;
+ float rightIncrementY2 = progressHeight * 0.5f;
+ float rightIncrementX3 = 0.0f;
+ float rightIncrementY3 = 0.0f;
+
+ path.cubicTo(new Point(balloonRect.left - balloonRect.getWidth() * 0.38f + rightIncrementX1, balloonRect.getCenter().getPointY() - balloonRect.getHeight() * 0.4f + rightIncrementY1),
+ new Point(balloonRect.left + balloonRect.getWidth() * 1.1f + rightIncrementX2, balloonRect.getCenter().getPointY() - balloonRect.getHeight() * 0.15f + rightIncrementY2),
+ new Point(balloonRect.left + balloonRect.getWidth() * 0.5f + rightIncrementX3, balloonRect.bottom + rightIncrementY3));
+
+// the results of the right final transformation
+// path.cubicTo(balloonRect.left + balloonRect.width() * 1.23f, balloonRect.centerY() - balloonRect.height() * 0.45f,
+// balloonRect.left + balloonRect.width() * 1.13f, balloonRect.centerY() + balloonRect.height() * 0.35f,
+// balloonRect.left + balloonRect.width() * 0.5f, balloonRect.bottom);
+
+ return path;
+ }
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderCircle.java b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderCircle.java
new file mode 100644
index 0000000000000000000000000000000000000000..29a3b1037bf4e0124ab5d08e1a3ccd2abe99e9ab
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderCircle.java
@@ -0,0 +1,126 @@
+package com.isoftstone.loadingview;
+
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.Rect;
+
+public class LoadingRanderCircle extends LoadingRander {
+ //private static final Interpolator ACCELERATE_DECELERATE_INTERPOLATOR = new AccelerateDecelerateInterpolator();
+
+ private static final long ANIMATION_DURATION = 2500;
+
+ private static final int DEFAULT_CIRCLE_COUNT = 5;
+
+ private static final float DEFAULT_BALL_RADIUS = 7.5f;
+ private static final float DEFAULT_WIDTH = 10.0f * 11;
+ private static final float DEFAULT_HEIGHT = 10.0f * 5;
+ private static final float DEFAULT_STROKE_WIDTH = 1.5f;
+
+ private static final Color DEFAULT_COLOR = Color.BLUE;
+
+ private final Paint mPaint = new Paint();
+
+ private int mColor;
+
+ private int mSwapIndex;
+ private int mBallCount;
+
+ private float mBallSideOffsets;
+ private float mBallCenterY;
+ private float mBallRadius;
+ private float mBallInterval;
+ private float mSwapBallOffsetX;
+ private float mSwapBallOffsetY;
+ private float mASwapThreshold;
+
+ private float mStrokeWidth;
+
+ public LoadingRanderCircle() {
+ super();
+ init();
+ adjustParams();
+ setupPaint();
+ }
+
+ private void init() {
+ mWidth = DensityUtil.dip2px(null, DEFAULT_WIDTH);
+ mHeight = DensityUtil.dip2px(null, DEFAULT_HEIGHT);
+ mBallRadius = DensityUtil.dip2px(null, DEFAULT_BALL_RADIUS);
+ mStrokeWidth = DensityUtil.dip2px(null, DEFAULT_STROKE_WIDTH);
+
+ //mColor = DEFAULT_COLOR;
+ //mDuration = ANIMATION_DURATION;
+ mBallCount = DEFAULT_CIRCLE_COUNT;
+
+ mBallInterval = mBallRadius;
+ }
+
+ private void adjustParams() {
+ mBallCenterY = mHeight ;
+ mBallSideOffsets = (mWidth - mBallRadius * 2 * mBallCount - mBallInterval * (mBallCount - 1)) / 2.0f;
+
+ mASwapThreshold = 1.0f / mBallCount;
+ }
+
+ private void setupPaint() {
+ mPaint.setColor(DEFAULT_COLOR);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ }
+
+ @Override
+ protected void draw(Canvas canvas, Rect bounds) {
+ int saveCount = canvas.save();
+
+ computeRender(mProgress);
+
+ for (int i = 0; i < mBallCount; i++) {
+ if (i == mSwapIndex) {
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
+ canvas.drawCircle(mBallSideOffsets + mBallRadius * (i * 2 + 1) + i * mBallInterval + mSwapBallOffsetX
+ , mBallCenterY - mSwapBallOffsetY, mBallRadius, mPaint);
+ } else if (i == (mSwapIndex + 1) % mBallCount) {
+ mPaint.setStyle(Paint.Style.STROKE_STYLE);
+ canvas.drawCircle(mBallSideOffsets + mBallRadius * (i * 2 + 1) + i * mBallInterval - mSwapBallOffsetX
+ , mBallCenterY + mSwapBallOffsetY, mBallRadius - mStrokeWidth / 2, mPaint);
+ } else {
+ mPaint.setStyle(Paint.Style.STROKE_STYLE);
+ canvas.drawCircle(mBallSideOffsets + mBallRadius * (i * 2 + 1) + i * mBallInterval, mBallCenterY
+ , mBallRadius - mStrokeWidth / 2, mPaint);
+ }
+ }
+
+ canvas.restoreToCount(saveCount);
+ }
+
+
+ protected void computeRender(float renderProgress) {
+ mSwapIndex = (int) (renderProgress / mASwapThreshold);
+
+ // Swap trace : x^2 + y^2 = r ^ 2
+ float swapTraceProgress = (
+ (renderProgress - mSwapIndex * mASwapThreshold) / mASwapThreshold);
+
+ float swapTraceRadius = mSwapIndex == mBallCount - 1
+ ? (mBallRadius * 2 * (mBallCount - 1) + mBallInterval * (mBallCount - 1)) / 2
+ : (mBallRadius * 2 + mBallInterval) / 2;
+
+ // Calculate the X offset of the swap ball
+ mSwapBallOffsetX = mSwapIndex == mBallCount - 1
+ ? -swapTraceProgress * swapTraceRadius * 2
+ : swapTraceProgress * swapTraceRadius * 2;
+
+ // if mSwapIndex == mBallCount - 1 then (swapTraceRadius, swapTraceRadius) as the origin of coordinates
+ // else (-swapTraceRadius, -swapTraceRadius) as the origin of coordinates
+ float xCoordinate = mSwapIndex == mBallCount - 1
+ ? mSwapBallOffsetX + swapTraceRadius
+ : mSwapBallOffsetX - swapTraceRadius;
+
+ // Calculate the Y offset of the swap ball
+ mSwapBallOffsetY = (float) (mSwapIndex % 2 == 0 && mSwapIndex != mBallCount - 1
+ ? Math.sqrt(Math.pow(swapTraceRadius, 2.0f) - Math.pow(xCoordinate, 2.0f))
+ : -Math.sqrt(Math.pow(swapTraceRadius, 2.0f) - Math.pow(xCoordinate, 2.0f)));
+
+ }
+
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderFish.java b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderFish.java
new file mode 100644
index 0000000000000000000000000000000000000000..835a84f3c922c326ba2b5a3c94f31d2a153f5ae5
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderFish.java
@@ -0,0 +1,220 @@
+package com.isoftstone.loadingview;
+
+import ohos.agp.render.*;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.Matrix;
+import ohos.agp.utils.Rect;
+import ohos.agp.utils.RectFloat;
+
+public class LoadingRanderFish extends LoadingRander {
+ //private Interpolator FISH_INTERPOLATOR = new FishInterpolator();
+
+ private static final float DEFAULT_PATH_FULL_LINE_SIZE = 7.0f;
+ private static final float DEFAULT_PATH_DOTTED_LINE_SIZE = DEFAULT_PATH_FULL_LINE_SIZE / 2.0f;
+ private static final float DEFAULT_RIVER_HEIGHT = DEFAULT_PATH_FULL_LINE_SIZE * 8.5f;
+ private static final float DEFAULT_RIVER_WIDTH = DEFAULT_PATH_FULL_LINE_SIZE * 5.5f;
+
+ private static final float DEFAULT_FISH_EYE_SIZE = DEFAULT_PATH_FULL_LINE_SIZE * 0.5f;
+ private static final float DEFAULT_FISH_WIDTH = DEFAULT_PATH_FULL_LINE_SIZE * 3.0f;
+ private static final float DEFAULT_FISH_HEIGHT = DEFAULT_PATH_FULL_LINE_SIZE * 4.5f;
+
+ private static final float DEFAULT_WIDTH = 200.0f;
+ private static final float DEFAULT_HEIGHT = 150.0f;
+ private static final float DEFAULT_RIVER_BANK_WIDTH = DEFAULT_PATH_FULL_LINE_SIZE;
+
+ private static final long ANIMATION_DURATION = 800;
+ private static final float DOTTED_LINE_WIDTH_COUNT = (8.5f + 5.5f - 2.0f) * 2.0f * 2.0f;
+ private static final float DOTTED_LINE_WIDTH_RATE = 1.0f / DOTTED_LINE_WIDTH_COUNT;
+
+ private final float[] FISH_MOVE_POINTS = new float[]{
+ DOTTED_LINE_WIDTH_RATE * 3.0f, DOTTED_LINE_WIDTH_RATE * 6.0f,
+ DOTTED_LINE_WIDTH_RATE * 15f, DOTTED_LINE_WIDTH_RATE * 18f,
+ DOTTED_LINE_WIDTH_RATE * 27.0f, DOTTED_LINE_WIDTH_RATE * 30.0f,
+ DOTTED_LINE_WIDTH_RATE * 39f, DOTTED_LINE_WIDTH_RATE * 42f,
+ };
+
+ private final float FISH_MOVE_POINTS_RATE = 1.0f / FISH_MOVE_POINTS.length;
+
+ private static final int DEFAULT_COLOR = Color.getIntColor("#ff0090d6");
+
+ private final Paint mPaint = new Paint();
+ private final RectFloat mTempBounds = new RectFloat();
+
+ private final float[] mFishHeadPos = new float[2];
+
+ private Path mRiverPath;
+ private PathMeasure mRiverMeasure;
+
+ private float mFishRotateDegrees;
+
+ private float mRiverBankWidth;
+ private float mRiverWidth;
+ private float mRiverHeight;
+ private float mFishWidth;
+ private float mFishHeight;
+ private float mFishEyeSize;
+ private float mPathFullLineSize;
+ private float mPathDottedLineSize;
+
+ private Color mColor;
+
+ public LoadingRanderFish() {
+ super();
+ init();
+ setupPaint();
+ }
+
+ private void init() {
+ mWidth = DensityUtil.dip2px(null, DEFAULT_WIDTH);
+ mHeight = DensityUtil.dip2px(null, DEFAULT_HEIGHT);
+ mRiverBankWidth = DensityUtil.dip2px(null, DEFAULT_RIVER_BANK_WIDTH);
+
+ mPathFullLineSize = DensityUtil.dip2px(null, DEFAULT_PATH_FULL_LINE_SIZE);
+ mPathDottedLineSize = DensityUtil.dip2px(null, DEFAULT_PATH_DOTTED_LINE_SIZE);
+ mFishWidth = DensityUtil.dip2px(null, DEFAULT_FISH_WIDTH);
+ mFishHeight = DensityUtil.dip2px(null, DEFAULT_FISH_HEIGHT);
+ mFishEyeSize = DensityUtil.dip2px(null, DEFAULT_FISH_EYE_SIZE);
+ mRiverWidth = DensityUtil.dip2px(null, DEFAULT_RIVER_WIDTH);
+ mRiverHeight = DensityUtil.dip2px(null, DEFAULT_RIVER_HEIGHT);
+
+ mColor = new Color(DEFAULT_COLOR);
+
+ //mDuration = ANIMATION_DURATION;
+ }
+
+ private void setupPaint() {
+ mPaint.setAntiAlias(true);
+ mPaint.setStrokeWidth(mRiverBankWidth);
+ mPaint.setStyle(Paint.Style.STROKE_STYLE);
+ mPaint.setStrokeJoin(Paint.Join.MITER_JOIN);
+ //mPaint.setPathEffect(new DashPathEffect(new float[]{mPathFullLineSize, mPathDottedLineSize}, mPathDottedLineSize));
+ }
+
+ @Override
+ protected void draw(Canvas canvas, Rect bounds) {
+ int saveCount = canvas.save();
+ RectFloat arcBounds = mTempBounds;
+ arcBounds.modify(bounds);
+
+ computeRender(mProgress);
+
+ mPaint.setColor(mColor);
+
+ //calculate fish clip bounds
+ //clip the width of the fish need to increase mPathDottedLineSize * 1.2f
+ RectFloat fishRectF = new RectFloat(mFishHeadPos[0] - mFishWidth / 2.0f - mPathDottedLineSize * 1.2f, mFishHeadPos[1] - mFishHeight / 2.0f,
+ mFishHeadPos[0] + mFishWidth / 2.0f + mPathDottedLineSize * 1.2f, mFishHeadPos[1] + mFishHeight / 2.0f);
+ Matrix matrix = new Matrix();
+ matrix.postRotate(mFishRotateDegrees, fishRectF.getCenter().getPointX(), fishRectF.getCenter().getPointY());
+ matrix.mapRect(fishRectF);
+
+ //draw river
+ int riverSaveCount = canvas.save();
+ mPaint.setStyle(Paint.Style.STROKE_STYLE);
+ canvas.clipRect(fishRectF, Canvas.ClipOp.DIFFERENCE);
+ canvas.drawPath(createRiverPath(arcBounds), mPaint);
+ canvas.restoreToCount(riverSaveCount);
+
+ //draw fish
+ int fishSaveCount = canvas.save();
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
+ canvas.rotate(mFishRotateDegrees, mFishHeadPos[0], mFishHeadPos[1]);
+ canvas.clipPath(createFishEyePath(mFishHeadPos[0], mFishHeadPos[1] - mFishHeight * 0.06f), Canvas.ClipOp.DIFFERENCE);
+ canvas.drawPath(createFishPath(mFishHeadPos[0], mFishHeadPos[1]), mPaint);
+ canvas.restoreToCount(fishSaveCount);
+
+ canvas.restoreToCount(saveCount);
+ }
+
+ private float calculateRotateDegrees(float fishProgress) {
+ if (fishProgress < FISH_MOVE_POINTS_RATE * 2) {
+ return 90;
+ }
+
+ if (fishProgress < FISH_MOVE_POINTS_RATE * 4) {
+ return 180;
+ }
+
+ if (fishProgress < FISH_MOVE_POINTS_RATE * 6) {
+ return 270;
+ }
+
+ return 0.0f;
+ }
+
+ protected void computeRender(float renderProgress) {
+ if (mRiverPath == null) {
+ return;
+ }
+
+ if (mRiverMeasure == null) {
+ mRiverMeasure = new PathMeasure(mRiverPath, false);
+ }
+
+ //float fishProgress = FISH_INTERPOLATOR.getInterpolation(renderProgress);
+ float fishProgress = renderProgress;
+
+ mRiverMeasure.getPosTan(mRiverMeasure.getLength() * fishProgress, mFishHeadPos, null);
+ mFishRotateDegrees = calculateRotateDegrees(fishProgress);
+ }
+
+
+
+ private Path createFishEyePath(float fishEyeCenterX, float fishEyeCenterY) {
+ Path path = new Path();
+ path.addCircle(fishEyeCenterX, fishEyeCenterY, mFishEyeSize, Path.Direction.COUNTER_CLOCK_WISE);
+
+ return path;
+ }
+
+ private Path createFishPath(float fishCenterX, float fishCenterY) {
+ Path path = new Path();
+
+ float fishHeadX = fishCenterX;
+ float fishHeadY = fishCenterY - mFishHeight / 2.0f;
+
+ //the head of the fish
+ path.moveTo(fishHeadX, fishHeadY);
+ //the left body of the fish
+ path.quadTo(fishHeadX - mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.222f, fishHeadX - mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.444f);
+ path.lineTo(fishHeadX - mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.666f);
+ path.lineTo(fishHeadX - mFishWidth * 0.5f, fishHeadY + mFishHeight * 0.8f);
+ path.lineTo(fishHeadX - mFishWidth * 0.5f, fishHeadY + mFishHeight);
+
+ //the tail of the fish
+ path.lineTo(fishHeadX, fishHeadY + mFishHeight * 0.9f);
+
+ //the right body of the fish
+ path.lineTo(fishHeadX + mFishWidth * 0.5f, fishHeadY + mFishHeight);
+ path.lineTo(fishHeadX + mFishWidth * 0.5f, fishHeadY + mFishHeight * 0.8f);
+ path.lineTo(fishHeadX + mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.666f);
+ path.lineTo(fishHeadX + mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.444f);
+ path.quadTo(fishHeadX + mFishWidth * 0.333f, fishHeadY + mFishHeight * 0.222f, fishHeadX, fishHeadY);
+
+ path.close();
+
+ return path;
+ }
+
+ private Path createRiverPath(RectFloat arcBounds) {
+ if (mRiverPath != null) {
+ return mRiverPath;
+ }
+
+ mRiverPath = new Path();
+
+ RectFloat rectF = new RectFloat(arcBounds.getCenter().getPointX() - mRiverWidth / 2.0f, arcBounds.getCenter().getPointY() - mRiverHeight / 2.0f,
+ arcBounds.getCenter().getPointX() + mRiverWidth / 2.0f, arcBounds.getCenter().getPointY() + mRiverHeight / 2.0f);
+
+ rectF.modify(rectF.left + mRiverBankWidth / 2.0f, rectF.top + mRiverBankWidth / 2.0f,
+ rectF.right - mRiverBankWidth / 2.0f, rectF.bottom - mRiverBankWidth / 2.0f);
+
+ //rectF.inset(mRiverBankWidth / 2.0f, mRiverBankWidth / 2.0f);
+
+ mRiverPath.addRect(rectF, Path.Direction.COUNTER_CLOCK_WISE);
+
+ return mRiverPath;
+ }
+
+
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderWatter.java b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderWatter.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e44b6ddd02b5d3d57f86b488ae731b2bbe4bbe1
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingRanderWatter.java
@@ -0,0 +1,302 @@
+package com.isoftstone.loadingview;
+
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.render.Path;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.Point;
+import ohos.agp.utils.Rect;
+import ohos.agp.utils.RectFloat;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class LoadingRanderWatter extends LoadingRander{
+ //private static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
+
+ private static final float DEFAULT_WIDTH = 200.0f;
+ private static final float DEFAULT_HEIGHT = 150.0f;
+ private static final float DEFAULT_STROKE_WIDTH = 1.5f;
+ private static final float DEFAULT_BOTTLE_WIDTH = 30;
+ private static final float DEFAULT_BOTTLE_HEIGHT = 43;
+ private static final float WATER_LOWEST_POINT_TO_BOTTLENECK_DISTANCE = 30;
+
+ private static final int DEFAULT_WAVE_COUNT = 5;
+ private static final int DEFAULT_WATER_DROP_COUNT = 25;
+
+ private static final int MAX_WATER_DROP_RADIUS = 5;
+ private static final int MIN_WATER_DROP_RADIUS = 1;
+
+ private static final int DEFAULT_BOTTLE_COLOR = Color.getIntColor("#FFAACBCB");
+ private static final int DEFAULT_WATER_COLOR = Color.getIntColor("#FF29E3F2");
+
+ private static final float DEFAULT_TEXT_SIZE = 7.0f;
+
+ private static final String LOADING_TEXT = "loading";
+ private static final long ANIMATION_DURATION = 11111;
+
+
+ private final Random mRandom = new Random();
+
+ private final Paint mPaint = new Paint();
+ private final RectFloat mCurrentBounds = new RectFloat();
+ private final RectFloat mBottleBounds = new RectFloat();
+ private final RectFloat mWaterBounds = new RectFloat();
+ private final RectFloat mLoadingBounds = new RectFloat();
+ private final List mWaterDropHolders = new ArrayList<>();
+
+
+
+ private float mBottleWidth;
+ private float mBottleHeight;
+ private float mStrokeWidth;
+ private float mWaterLowestPointToBottleneckDistance;
+
+ private int mBottleColor;
+ private int mWaterColor;
+
+ private int mWaveCount;
+
+ public LoadingRanderWatter() {
+ init();
+ setupPaint();
+ }
+
+ private void init() {
+ mTextSize = DensityUtil.dip2px(null, DEFAULT_TEXT_SIZE);
+
+ mWidth = DensityUtil.dip2px(null, DEFAULT_WIDTH);
+ mHeight = DensityUtil.dip2px(null, DEFAULT_HEIGHT);
+ mStrokeWidth = DensityUtil.dip2px(null, DEFAULT_STROKE_WIDTH);
+
+ mBottleWidth = DensityUtil.dip2px(null, DEFAULT_BOTTLE_WIDTH);
+ mBottleHeight = DensityUtil.dip2px(null, DEFAULT_BOTTLE_HEIGHT);
+ mWaterLowestPointToBottleneckDistance = DensityUtil.dip2px(null, WATER_LOWEST_POINT_TO_BOTTLENECK_DISTANCE);
+
+ mBottleColor = DEFAULT_BOTTLE_COLOR;
+ mWaterColor = DEFAULT_WATER_COLOR;
+
+ mWaveCount = DEFAULT_WAVE_COUNT;
+
+ //mDuration = ANIMATION_DURATION;
+ }
+
+ private void setupPaint() {
+ mPaint.setAntiAlias(true);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ mPaint.setStrokeJoin(Paint.Join.ROUND_JOIN);
+ }
+
+ @Override
+ protected void draw(Canvas canvas, Rect bounds) {
+ int saveCount = canvas.save();
+
+ String string = new String();
+ String.format(string, "mProgress = %f", mProgress);
+ canvas.drawText(mPaint, string, 0 , 100);
+
+ RectFloat arcBounds = mCurrentBounds;
+ arcBounds.modify(bounds);
+
+ computeRender(mProgress);
+
+ //draw bottle
+ mPaint.setStyle(Paint.Style.STROKE_STYLE);
+ mPaint.setColor(new Color(mBottleColor));
+ canvas.drawPath(createBottlePath(mBottleBounds), mPaint);
+
+ //draw water
+ mPaint.setStyle(Paint.Style.FILLANDSTROKE_STYLE);
+ mPaint.setColor(new Color(mWaterColor));
+ canvas.drawPath(createWaterPath(mWaterBounds, mProgress), mPaint);
+
+ //draw water drop
+ mPaint.setStyle(Paint.Style.FILL_STYLE);
+ mPaint.setColor(new Color(mWaterColor));
+ for (LoadingRanderWatter.WaterDropHolder waterDropHolder : mWaterDropHolders) {
+ if (waterDropHolder.mNeedDraw) {
+ canvas.drawCircle(waterDropHolder.mInitX, waterDropHolder.mCurrentY, waterDropHolder.mRadius, mPaint);
+ }
+ }
+
+ //draw loading text
+ mPaint.setColor(new Color(mBottleColor));
+ canvas.drawText(mPaint, LOADING_TEXT, mBottleBounds.getCenter().getPointX() - mLoadingBounds.getWidth() / 2.0f,
+ mBottleBounds.bottom + mBottleBounds.getHeight() * 0.2f);
+
+ canvas.restoreToCount(saveCount);
+ //mProgress += 0.1f;
+ //if (mProgress >= 1.0f) {
+ // mProgress = 0.0f;
+ //}
+ computeRender(mProgress);
+ }
+
+ protected void computeRender(float renderProgress) {
+ if (mCurrentBounds.getWidth() <= 0) {
+ return;
+ }
+
+ RectFloat arcBounds = mCurrentBounds;
+ //compute gas tube bounds
+ mBottleBounds.modify(arcBounds.getCenter().getPointX() - mBottleWidth / 2.0f, arcBounds.getCenter().getPointY() - mBottleHeight / 2.0f,
+ arcBounds.getCenter().getPointX() + mBottleWidth / 2.0f, arcBounds.getCenter().getPointY() + mBottleHeight / 2.0f);
+ //compute pipe body bounds
+ mWaterBounds.modify(mBottleBounds.left + mStrokeWidth * 1.5f, mBottleBounds.top + mWaterLowestPointToBottleneckDistance,
+ mBottleBounds.right - mStrokeWidth * 1.5f, mBottleBounds.bottom - mStrokeWidth * 1.5f);
+
+ //compute wave progress
+ float totalWaveProgress = renderProgress * mWaveCount;
+ float currentWaveProgress = totalWaveProgress - ((int) totalWaveProgress);
+
+ mProgress = renderProgress;
+ if (currentWaveProgress > 0.5f) {
+ //mProgress = 1.0f - MATERIAL_INTERPOLATOR.getInterpolation((currentWaveProgress - 0.5f) * 2.0f);
+ } else {
+ //mProgress = MATERIAL_INTERPOLATOR.getInterpolation(currentWaveProgress * 2.0f);
+ }
+
+ //init water drop holders
+ if (mWaterDropHolders.isEmpty()) {
+ initWaterDropHolders(mBottleBounds, mWaterBounds);
+ }
+
+ //compute the location of these water drops
+ for (LoadingRanderWatter.WaterDropHolder waterDropHolder : mWaterDropHolders) {
+ if (waterDropHolder.mDelayDuration < renderProgress
+ && waterDropHolder.mDelayDuration + waterDropHolder.mDuration > renderProgress) {
+ float riseProgress = (renderProgress - waterDropHolder.mDelayDuration) / waterDropHolder.mDuration;
+ riseProgress = riseProgress < 0.5f ? riseProgress * 2.0f : 1.0f - (riseProgress - 0.5f) * 2.0f;
+ waterDropHolder.mCurrentY = waterDropHolder.mInitY -
+ riseProgress * waterDropHolder.mRiseHeight;
+ waterDropHolder.mNeedDraw = true;
+ } else {
+ waterDropHolder.mNeedDraw = false;
+ }
+ }
+
+ //measure loading text
+ mPaint.setTextSize((int) mTextSize);
+ //mPaint.getTextBounds(LOADING_TEXT, 0, LOADING_TEXT.length(), mLoadingBounds);
+ }
+
+ private Path createBottlePath(RectFloat bottleRect) {
+ float bottleneckWidth = bottleRect.getWidth() * 0.3f;
+ float bottleneckHeight = bottleRect.getHeight() * 0.415f;
+ float bottleneckDecorationWidth = bottleneckWidth * 1.1f;
+ float bottleneckDecorationHeight = bottleneckHeight * 0.167f;
+
+ Path path = new Path();
+ //draw the left side of the bottleneck decoration
+ path.moveTo(bottleRect.getCenter().getPointX() - bottleneckDecorationWidth * 0.5f, bottleRect.top);
+ path.quadTo(bottleRect.getCenter().getPointX() - bottleneckDecorationWidth * 0.5f - bottleneckWidth * 0.15f, bottleRect.top + bottleneckDecorationHeight * 0.5f,
+ bottleRect.getCenter().getPointX() - bottleneckWidth * 0.5f, bottleRect.top + bottleneckDecorationHeight);
+ path.lineTo(bottleRect.getCenter().getPointX() - bottleneckWidth * 0.5f, bottleRect.top + bottleneckHeight);
+
+ //draw the left side of the bottle's body
+ float radius = (bottleRect.getWidth() - mStrokeWidth) / 2.0f;
+ float centerY = bottleRect.bottom - 0.86f * radius;
+ RectFloat bodyRect = new RectFloat(bottleRect.left, centerY - radius, bottleRect.right, centerY + radius);
+ path.addArc(bodyRect, 255, -135);
+
+ //draw the bottom of the bottle
+ float bottleBottomWidth = bottleRect.getWidth() / 2.0f;
+ path.lineTo(bottleRect.getCenter().getPointX() - bottleBottomWidth / 2.0f, bottleRect.bottom);
+ path.lineTo(bottleRect.getCenter().getPointX() + bottleBottomWidth / 2.0f, bottleRect.bottom);
+
+ //draw the right side of the bottle's body
+ path.addArc(bodyRect, 60, -135);
+
+ //draw the right side of the bottleneck decoration
+ path.lineTo(bottleRect.getCenter().getPointX() + bottleneckWidth * 0.5f, bottleRect.top + bottleneckDecorationHeight);
+ path.quadTo(bottleRect.getCenter().getPointX() + bottleneckDecorationWidth * 0.5f + bottleneckWidth * 0.15f, bottleRect.top + bottleneckDecorationHeight * 0.5f,
+ bottleRect.getCenter().getPointX() + bottleneckDecorationWidth * 0.5f, bottleRect.top);
+
+ return path;
+ }
+
+ private Path createWaterPath(RectFloat waterRect, float progress) {
+ Path path = new Path();
+
+ path.moveTo(waterRect.left, waterRect.top);
+
+ //Similar to the way draw the bottle's bottom sides
+ float radius = (waterRect.getWidth() - mStrokeWidth) / 2.0f;
+ float centerY = waterRect.bottom - 0.86f * radius;
+ float bottleBottomWidth = waterRect.getWidth() / 2.0f;
+ RectFloat bodyRect = new RectFloat(waterRect.left, centerY - radius, waterRect.right, centerY + radius);
+
+ path.addArc(bodyRect, 187.5f, -67.5f);
+ path.lineTo(waterRect.getCenter().getPointX() - bottleBottomWidth / 2.0f, waterRect.bottom);
+ path.lineTo(waterRect.getCenter().getPointX() + bottleBottomWidth / 2.0f, waterRect.bottom);
+ path.addArc(bodyRect, 60, -67.5f);
+
+ //draw the water waves
+ float cubicXChangeSize = waterRect.getWidth() * 0.35f * progress;
+ float cubicYChangeSize = waterRect.getHeight() * 1.2f * progress;
+ path.cubicTo(new Point(waterRect.left + waterRect.getWidth() * 0.80f - cubicXChangeSize,
+ waterRect.top - waterRect.getHeight() * 1.2f + cubicYChangeSize),
+ new Point(waterRect.left + waterRect.getWidth() * 0.55f - cubicXChangeSize,
+ waterRect.top - cubicYChangeSize),
+ new Point(waterRect.left,
+ waterRect.top - mStrokeWidth / 2.0f));
+
+ path.lineTo(waterRect.left, waterRect.top);
+
+ return path;
+ }
+
+ private void initWaterDropHolders(RectFloat bottleRect, RectFloat waterRect) {
+ float bottleRadius = bottleRect.getWidth() / 2.0f;
+ float lowestWaterPointY = waterRect.top;
+ float twoSidesInterval = 0.2f * bottleRect.getWidth();
+ float atLeastDelayDuration = 0.1f;
+
+ float unitDuration = 0.1f;
+ float delayDurationRange = 0.6f;
+ int radiusRandomRange = MAX_WATER_DROP_RADIUS - MIN_WATER_DROP_RADIUS;
+ float currentXRandomRange = bottleRect.getWidth() * 0.6f;
+
+ for (int i = 0; i < DEFAULT_WATER_DROP_COUNT; i++) {
+ LoadingRanderWatter.WaterDropHolder waterDropHolder = new LoadingRanderWatter.WaterDropHolder();
+ waterDropHolder.mRadius = MIN_WATER_DROP_RADIUS + mRandom.nextInt(radiusRandomRange);
+ waterDropHolder.mInitX = bottleRect.left + twoSidesInterval + mRandom.nextFloat() * currentXRandomRange;
+ waterDropHolder.mInitY = lowestWaterPointY + waterDropHolder.mRadius / 2.0f;
+ waterDropHolder.mRiseHeight = getMaxRiseHeight(bottleRadius, waterDropHolder.mRadius, waterDropHolder.mInitX - bottleRect.left)
+ * (0.2f + 0.8f * mRandom.nextFloat());
+ waterDropHolder.mDelayDuration = atLeastDelayDuration + mRandom.nextFloat() * delayDurationRange;
+ waterDropHolder.mDuration = waterDropHolder.mRiseHeight / bottleRadius * unitDuration;
+
+ mWaterDropHolders.add(waterDropHolder);
+ }
+ }
+
+ private float getMaxRiseHeight(float bottleRadius, float waterDropRadius, float currentX) {
+ float coordinateX = currentX - bottleRadius;
+ float bottleneckRadius = bottleRadius * 0.3f;
+ if (coordinateX - waterDropRadius > -bottleneckRadius
+ && coordinateX + waterDropRadius < bottleneckRadius) {
+ return bottleRadius * 2.0f;
+ }
+
+ return (float) (Math.sqrt(Math.pow(bottleRadius, 2.0f) - Math.pow(coordinateX, 2.0f)) - waterDropRadius);
+ }
+
+
+
+ private class WaterDropHolder {
+ public float mCurrentY;
+
+ public float mInitX;
+ public float mInitY;
+ public float mDelayDuration;
+ public float mRiseHeight;
+
+ public float mRadius;
+ public float mDuration;
+
+ public boolean mNeedDraw;
+ }
+
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingView.java b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingView.java
new file mode 100644
index 0000000000000000000000000000000000000000..449e6b7e977d72d39ae6d5d45881b376bc8f3a87
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/java/com/isoftstone/loadingview/LoadingView.java
@@ -0,0 +1,98 @@
+package com.isoftstone.loadingview;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.render.Canvas;
+import ohos.agp.utils.DimensFloat;
+import ohos.agp.utils.Point;
+import ohos.agp.utils.Rect;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class LoadingView extends Component implements Component.DrawTask {
+
+ public enum LoadingViewType {
+ // 支持的类型
+ WATER, BALLOON, FISH, CIRCLE;
+ }
+
+ // 动画
+ private AnimatorValue animatorValue;
+
+ // 绘制类
+ private LoadingRander loadingRander;
+
+
+ public LoadingView(Context context) {
+ super(context);
+ init();
+ }
+
+ public LoadingView(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ init();
+ }
+
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ // 获取组件的大小,进行绘制
+ DimensFloat pt = getComponentSize();
+ Rect rect = new Rect(0,0,pt.getSizeXToInt(),pt.getSizeYToInt());
+ loadingRander.draw(canvas, rect);
+ }
+
+ // 动画侦听函数
+ private final AnimatorValue.ValueUpdateListener mAnimatorUpdateListener
+ = new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ if (loadingRander != null) {
+ loadingRander.setProgess(v);
+ }
+ invalidate();
+ }
+ };
+
+ private void init() {
+ // 启动动画
+ animatorValue = new AnimatorValue();
+ animatorValue.setCurveType(Animator.CurveType.LINEAR);
+ animatorValue.setDelay(100);
+ animatorValue.setLoopedCount(Animator.INFINITE);
+ animatorValue.setDuration(2000);
+ animatorValue.setValueUpdateListener(mAnimatorUpdateListener);
+ animatorValue.start();
+ }
+
+ // 设置动画的类型
+ public boolean SetType(LoadingViewType type) {
+ switch (type) {
+ case WATER:
+ loadingRander = new LoadingRanderWatter();
+ break;
+
+ case BALLOON:
+ loadingRander = new LoadingRanderBalloon();
+ break;
+
+ case FISH:
+ loadingRander = new LoadingRanderFish();
+ break;
+
+ case CIRCLE:
+ loadingRander = new LoadingRanderCircle();
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+ }
+
+
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/resources/base/element/string.json b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..63ffcfdbfd1b56ddb873ea4e53da29428fd00489
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/loadingview/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "LoadingView"
+ }
+ ]
+}
diff --git a/008.LoadingDrawable_OpenHarmony_master/code/settings.gradle b/008.LoadingDrawable_OpenHarmony_master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..c8cf25f33a4b5e829911155bb5b1ddf96040fa00
--- /dev/null
+++ b/008.LoadingDrawable_OpenHarmony_master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':loadingview'
diff --git "a/008.LoadingDrawable_OpenHarmony_master/doc/008.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204LoadingView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/008.LoadingDrawable_OpenHarmony_master/doc/008.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204LoadingView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..72b8ccf359b84238e42bcb4410db880e4fd0ea7a
Binary files /dev/null and "b/008.LoadingDrawable_OpenHarmony_master/doc/008.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204LoadingView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/009.EventBus-OpenHarmony-master/code/.gitignore b/009.EventBus-OpenHarmony-master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/009.EventBus-OpenHarmony-master/code/.idea/.gitignore b/009.EventBus-OpenHarmony-master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/009.EventBus-OpenHarmony-master/code/.idea/compiler.xml b/009.EventBus-OpenHarmony-master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/.idea/gradle.xml b/009.EventBus-OpenHarmony-master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f0b6549e50dad37933cc5898dc35391764feb555
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/.idea/gradle.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/.idea/jarRepositories.xml b/009.EventBus-OpenHarmony-master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/.idea/misc.xml b/009.EventBus-OpenHarmony-master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/build.gradle b/009.EventBus-OpenHarmony-master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..613f3e6a0b18b7a502df3b3655e61411ae191520
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/.gitignore b/009.EventBus-OpenHarmony-master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/009.EventBus-OpenHarmony-master/code/entry/build.gradle b/009.EventBus-OpenHarmony-master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5b676898b964683517e5275b9d2f77aaf52ceed2
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/libs/eventbusmodule.har b/009.EventBus-OpenHarmony-master/code/entry/libs/eventbusmodule.har
new file mode 100644
index 0000000000000000000000000000000000000000..8d1f15aadba7c7fddedf181783321e70d3591e3c
Binary files /dev/null and b/009.EventBus-OpenHarmony-master/code/entry/libs/eventbusmodule.har differ
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/config.json b/009.EventBus-OpenHarmony-master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..39eff0ceb6a0949626650df91a6477ee0b0c7441
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/config.json
@@ -0,0 +1,58 @@
+{
+ "app": {
+ "bundleName": "com.isoft.eventbus",
+ "vendor": "isoft",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 3,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoft.eventbus",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.isoft.eventbus.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.isoft.eventbus.SecondAbility",
+ "icon": "$media:icon",
+ "description": "$string:secondability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/EventMessage.java b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/EventMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fb295b5c40d822ff1debad74c002edd2b9f3cdb
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/EventMessage.java
@@ -0,0 +1,22 @@
+package com.isoft.eventbus;
+
+public class EventMessage {
+ private String message;
+ private int type;
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/MainAbility.java b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..31c6320d6d2586fdc5c3d50a7b89aab8ee547c43
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/MainAbility.java
@@ -0,0 +1,13 @@
+package com.isoft.eventbus;
+
+import com.isoft.eventbus.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/MyApplication.java b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd1ac9592161b69b4f5fb327e58576c964556696
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/MyApplication.java
@@ -0,0 +1,10 @@
+package com.isoft.eventbus;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/SecondAbility.java b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/SecondAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..f53d7b9df5056a3fbe50b1868d758c9c44679955
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/SecondAbility.java
@@ -0,0 +1,13 @@
+package com.isoft.eventbus;
+
+import com.isoft.eventbus.slice.SecondAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class SecondAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(SecondAbilitySlice.class.getName());
+ }
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/slice/MainAbilitySlice.java b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4d29852e1b898a66edddc13ab9839db277511e6
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/slice/MainAbilitySlice.java
@@ -0,0 +1,67 @@
+package com.isoft.eventbus.slice;
+
+import com.isoft.eventbus.EventMessage;
+import com.isoft.eventbus.ResourceTable;
+import com.isoft.eventbusmodule.EventBus;
+import com.isoft.eventbusmodule.Subscribe;
+import com.isoft.eventbusmodule.ThreadMode;
+import ohos.aafwk.ability.AbilityForm;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.ability.OnClickListener;
+import ohos.aafwk.ability.ViewsStatus;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+
+
+public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
+ private Text tvResult;
+ private Button button;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ EventBus.getDefault().register(this);
+ tvResult=(Text) findComponentById(ResourceTable.Id_text);
+ button=(Button) findComponentById(ResourceTable.Id_button);
+ button.setClickedListener(this);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+
+ @Override
+ public void onClick(Component component) {
+ Intent secondIntent = new Intent();
+ // 指定待启动FA的bundleName和abilityName
+ Operation operation = new Intent.OperationBuilder()
+ .withDeviceId("")
+ .withBundleName("com.isoft.eventbus")
+ .withAbilityName("com.isoft.eventbus.SecondAbility")
+ .build();
+ secondIntent.setOperation(operation);
+ // 通过AbilitySlice的startAbility接口实现启动另一个页面
+ startAbility(secondIntent);
+ }
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void receiveMessage(EventMessage eventMessage){
+ tvResult.setText(eventMessage.getMessage());
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ EventBus.getDefault().unregister(this);
+ }
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/slice/SecondAbilitySlice.java b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/slice/SecondAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..8112bd7a07f70964dfeab0eec1bd321ca2877c17
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/java/com/isoft/eventbus/slice/SecondAbilitySlice.java
@@ -0,0 +1,38 @@
+package com.isoft.eventbus.slice;
+
+import com.isoft.eventbus.EventMessage;
+import com.isoft.eventbus.ResourceTable;
+import com.isoft.eventbusmodule.EventBus;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+
+public class SecondAbilitySlice extends AbilitySlice implements Component.ClickedListener {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_second);
+ Button btSend=(Button)findComponentById(ResourceTable.Id_button_send);
+ btSend.setClickedListener(this);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+ @Override
+ public void onClick(Component component) {
+ EventMessage eventMessage=new EventMessage();
+ eventMessage.setMessage("您有新消息啦");
+ EventBus.getDefault().post(eventMessage);
+ terminateAbility();
+ }
+
+}
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/element/string.json b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..040e122c48b77b7a891cd470c17b301797d7cbc0
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "EventBus"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "secondability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_second.xml b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_second.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_second.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_button.xml b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..33c9570e6fa1d6eafa5118621676d1b51325dc4b
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_button.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..29356cb83abfa84dcdb7d9a72aa41d4df792d1fc
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_second.xml b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_second.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a7471049c52a4f5fa89b5eeb32f629f9949f2a42
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_second.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/009.EventBus-OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/009.EventBus-OpenHarmony-master/code/settings.gradle b/009.EventBus-OpenHarmony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07
--- /dev/null
+++ b/009.EventBus-OpenHarmony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry'
diff --git "a/009.EventBus-OpenHarmony-master/doc/009.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204EventBus\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227\344\275\277\347\224\250\350\257\264\346\230\216.doc" "b/009.EventBus-OpenHarmony-master/doc/009.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204EventBus\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227\344\275\277\347\224\250\350\257\264\346\230\216.doc"
new file mode 100644
index 0000000000000000000000000000000000000000..af69797d87171e2d3bb1760a84b80f9012db6b12
Binary files /dev/null and "b/009.EventBus-OpenHarmony-master/doc/009.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204EventBus\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227\344\275\277\347\224\250\350\257\264\346\230\216.doc" differ
diff --git a/010.switchButton_OpenHarmony-master/code/.gitignore b/010.switchButton_OpenHarmony-master/code/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/010.switchButton_OpenHarmony-master/code/.idea/.gitignore b/010.switchButton_OpenHarmony-master/code/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/010.switchButton_OpenHarmony-master/code/.idea/compiler.xml b/010.switchButton_OpenHarmony-master/code/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/.idea/gradle.xml b/010.switchButton_OpenHarmony-master/code/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..48f27415633e3c33c42bc06ac358a5fc136eb7d6
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/.idea/jarRepositories.xml b/010.switchButton_OpenHarmony-master/code/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/.idea/misc.xml b/010.switchButton_OpenHarmony-master/code/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_-1993957388.json b/010.switchButton_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_-1993957388.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.idea/previewer/phone/phoneSettingConfig_-1993957388.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/.idea/previewer/previewConfig.json b/010.switchButton_OpenHarmony-master/code/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..1b80590327df2f2320b0562b93ab81be64faea67
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/.idea/previewer/previewConfig.json
@@ -0,0 +1,9 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "E:\\workspace\\HarmonyOS\\DevEcoStudioProjects\\MyApplication2\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/build.gradle b/010.switchButton_OpenHarmony-master/code/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0e1be68cdeea3cd399f5777b9a7af0797746580f
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/010.switchButton_OpenHarmony-master/code/entry/.gitignore b/010.switchButton_OpenHarmony-master/code/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/010.switchButton_OpenHarmony-master/code/entry/build.gradle b/010.switchButton_OpenHarmony-master/code/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1f70229191ab382513c91174ed1be883e6070e77
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ compile project(path: ':switchbutton')
+}
diff --git a/010.switchButton_OpenHarmony-master/code/entry/libs/switchbutton-debug.har b/010.switchButton_OpenHarmony-master/code/entry/libs/switchbutton-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..e1f9d7fe85fbb1b2c7abea4b9686a726ccbc2db4
Binary files /dev/null and b/010.switchButton_OpenHarmony-master/code/entry/libs/switchbutton-debug.har differ
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/config.json b/010.switchButton_OpenHarmony-master/code/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..41febd5de2d1472caf63cf332281dca8ca779068
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.myapplication",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.myapplication.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java b/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..813ed4e7594dc5d3545f66e7f9ac76aab74be555
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.myapplication;
+
+import com.example.myapplication.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java b/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..33915e2cc691b0fa169fd0a13e2262ac3925bafd
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.myapplication;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java b/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d743e725f8a5024438a5630a9cb484a5d13d050
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java
@@ -0,0 +1,131 @@
+package com.example.myapplication.slice;
+
+import com.example.myapplication.ResourceTable;
+import com.isoftstone.switchbutton.SwitchButton;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.*;
+import ohos.agp.window.dialog.ToastDialog;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
+ private static HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x000111,"SwitchButton");
+ private ScrollView scrollView;
+ private Button mbtn_toggle_ani,mbtn_toggle_ani_no_event,mbtn_toggle_not_ani,mbtn_toggle_not_ani_no_event;
+ private SwitchButton mListenerSb, mListenerDistinguishSb, mLongSb, mToggleSb, mCheckedSb, mDelaySb, mForceOpenSb, mForceOpenControlSb;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+// SwitchButton button = (SwitchButton) findComponentById(ResourceTable.Id_switchBtn1);
+ initView();
+ }
+
+ private void initView(){
+ findView();
+ // work with listener
+ mListenerSb.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener(){
+ @Override
+ public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
+// mListenerFinish.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE);
+ if (mListenerDistinguishSb.isChecked() != isChecked) {
+ mListenerDistinguishSb.setChecked(isChecked);
+ }
+ }
+
+ });
+
+
+ // check in check
+ mForceOpenSb.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener(){
+ @Override
+ public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
+// mListenerFinish.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE);
+ if (mForceOpenControlSb.isChecked()) {
+// toast("Call mForceOpenSb.setChecked(true); in on CheckedChanged");
+ mForceOpenSb.setChecked(true);
+ }
+ }
+
+ });
+
+
+ // check in check
+ mToggleSb.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener(){
+ @Override
+ public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
+// mListenerFinish.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE);
+ HiLog.info(label,"Toggle SwitchButton new check state: " + (isChecked ? "Checked" : "Unchecked"));
+ toast("Toggle SwitchButton new check state: " + (isChecked ? "Checked" : "Unchecked"));
+ }
+
+ });
+
+
+ }
+
+ private void findView() {
+ scrollView = (ScrollView) findComponentById(ResourceTable.Id_scrollview);
+ mListenerSb = (SwitchButton) findComponentById(ResourceTable.Id_switchButton3_1);
+ mListenerDistinguishSb = (SwitchButton) findComponentById(ResourceTable.Id_switchButton3_2);
+ mForceOpenSb = (SwitchButton) findComponentById(ResourceTable.Id_switchButton3_focus_open);
+ mForceOpenControlSb = (SwitchButton) findComponentById(ResourceTable.Id_switchButton3_focus_open_control);
+
+ mToggleSb = (SwitchButton) findComponentById(ResourceTable.Id_switchButton3_use_toggle);
+ mbtn_toggle_ani = (Button) findComponentById(ResourceTable.Id_toggle_ani);
+ mbtn_toggle_ani.setClickedListener(this::onClick);
+ mbtn_toggle_ani_no_event = (Button) findComponentById(ResourceTable.Id_toggle_ani_no_event);
+ mbtn_toggle_ani_no_event.setClickedListener(this::onClick);
+ mbtn_toggle_not_ani = (Button) findComponentById(ResourceTable.Id_toggle_not_ani);
+ mbtn_toggle_not_ani.setClickedListener(this::onClick);
+ mbtn_toggle_not_ani_no_event = (Button) findComponentById(ResourceTable.Id_toggle_not_ani_no_event);
+ mbtn_toggle_not_ani_no_event.setClickedListener(this::onClick);
+
+
+ }
+
+
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+ private void toast(String str){
+ new ToastDialog(getContext())
+ .setText(str)
+ .show();
+ }
+
+ @Override
+ public void onClick(Component component) {
+ switch (component.getId()){
+ case ResourceTable.Id_toggle_ani:
+ HiLog.info(label,"click Id_toggle_ani");
+ try{ mToggleSb.toggle();}
+ catch(Exception e){
+ HiLog.info(label,"Exception:"+e.toString());
+ }
+ break;
+ case ResourceTable.Id_toggle_ani_no_event:
+ mToggleSb.toggleNoEvent();
+ break;
+ case ResourceTable.Id_toggle_not_ani:
+ mToggleSb.toggleImmediately();
+ break;
+ case ResourceTable.Id_toggle_not_ani_no_event:
+ mToggleSb.toggleImmediatelyNoEvent();
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/element/color.json b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..cc4e599430db3069cbc358f305f8224c8ae3f8b6
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,20 @@
+{
+ "color":[
+ {
+ "name":"thumb_on",
+ "value":"#1E90FF"
+ },
+ {
+ "name":"thumb_off",
+ "value":"#FFFFFF"
+ },
+ {
+ "name":"track_on",
+ "value":"#87CEFA"
+ },
+ {
+ "name":"track_off",
+ "value":"#808080"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..e5a87e0da9974d98d4c3c1e27070121a4815d1af
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,60 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "use_listener",
+ "value": "Work with listener"
+ },
+ {
+ "name": "use_check_in_check",
+ "value": "call setChecked(boolean)/setCheckedImmediately(boolean) in OnCheckedChangeListener\\nIf the second SwitchButton is checked, the first one was \"locked\" to checked state."
+ },
+ {
+ "name": "use_toggle",
+ "value": "2 ways to TOGGLE"
+ },
+ {
+ "name": "use_checked",
+ "value": "2 ways to SET_CHECKED"
+ },
+ {
+ "name": "toggle_animated",
+ "value": "toggle();"
+ },
+ {
+ "name": "toggle_animated_no_event",
+ "value": "toggleNoEvent()"
+ },
+ {
+ "name": "toggle_not_animated",
+ "value": "toggleImmediately()"
+ },
+ {
+ "name": "toggle_not_animated_no_event",
+ "value": "toggleImmediatelyNoEvent();"
+ },
+ {
+ "name": "checked_animated",
+ "value": "setChecked(boolean)"
+ },
+ {
+ "name": "checked_animated_no_event",
+ "value": "setCheckedNoEvent(boolean)"
+ },
+ {
+ "name": "checked_not_animated",
+ "value": "setCheckedImmediately(boolean)"
+ },
+ {
+ "name": "checked_not_animated_no_event",
+ "value": "setCheckedImmediatelyNoEvent(boolean)"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_button.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ff3e6cc118d810e13e76ca68eeab533a5e0b2f23
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/background_button.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_back_off.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_back_off.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0eaecb65b9f5e8ec01a0d58041b5b6aea139dba0
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_back_off.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_back_on.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_back_on.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61d321928e92541e74743def956ba5f364d5280c
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_back_on.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_thumb_off.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_thumb_off.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8cea2e3cd004af1903beb3d94285a609bb2f141c
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_thumb_off.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_thumb_on.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_thumb_on.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f620d778a3c53a03175e685618adf619c0f94e07
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/graphic/button_thumb_on.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fb231569afca54ab0c2ffea8aa537399e4eb5273
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,260 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_switchButton.xml b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_switchButton.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e418614df4e8ffb741db9b29bb4dd48f9a3c0f47
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/layout/ability_switchButton.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/media/flower.png b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/media/flower.png
new file mode 100644
index 0000000000000000000000000000000000000000..a55b59cf221877bd63cc7a1bb23db3aae5dd475b
Binary files /dev/null and b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/media/flower.png differ
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/010.switchButton_OpenHarmony-master/code/entry/src/main/resources/base/media/icon.png differ
diff --git a/010.switchButton_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java b/010.switchButton_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..160d520624e9b69a368ef2d9903f914e1be01474
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/entry/src/test/java/com/example/myapplication/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.myapplication;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/010.switchButton_OpenHarmony-master/code/gradle.properties b/010.switchButton_OpenHarmony-master/code/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/010.switchButton_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar b/010.switchButton_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/010.switchButton_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/010.switchButton_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties b/010.switchButton_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/010.switchButton_OpenHarmony-master/code/gradlew b/010.switchButton_OpenHarmony-master/code/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/010.switchButton_OpenHarmony-master/code/gradlew.bat b/010.switchButton_OpenHarmony-master/code/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/010.switchButton_OpenHarmony-master/code/settings.gradle b/010.switchButton_OpenHarmony-master/code/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..ce28fad5f4216e4d456b44ce2b417d329d8019e8
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':switchbutton'
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/.gitignore b/010.switchButton_OpenHarmony-master/code/switchbutton/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/build.gradle b/010.switchButton_OpenHarmony-master/code/switchbutton/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5e58bb7146b04e3cd72644da4bcf2fae9cbd59bf
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/config.json b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..52fc97577d3dba01bc2e1c17de6181f005c6d1b1
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.switchbutton",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "switchbutton",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/java/com/isoftstone/switchbutton/ColorUtils.java b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/java/com/isoftstone/switchbutton/ColorUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..08b28a7c45e52f5281481870769fe0d0baa66fe7
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/java/com/isoftstone/switchbutton/ColorUtils.java
@@ -0,0 +1,101 @@
+package com.isoftstone.switchbutton;
+
+import ohos.agp.components.ComponentState;
+import ohos.agp.utils.Color;
+
+/**
+ * Generate thumb and background color state list use tintColor
+ * Created by kyle on 15/11/4.
+ */
+public class ColorUtils {
+
+ private static int defaultColor = Color.CYAN.getValue();
+
+ static int getDefaultColor(){
+ return defaultColor;
+ }
+
+ static int[][] ThumbColorstates = new int[][]{
+ {ComponentState.COMPONENT_STATE_CHECKED},
+ {ComponentState.COMPONENT_STATE_EMPTY},
+ {ComponentState.COMPONENT_STATE_DISABLED},
+ {ComponentState.COMPONENT_STATE_PRESSED}
+ };
+
+ static int[] ThumbColors = new int[]{
+ Color.BLUE.getValue(),
+ Color.WHITE.getValue(),
+ Color.LTGRAY.getValue(),
+ Color.BLUE.getValue()
+ };
+
+ static int[] BackColors = new int[]{
+ Color.YELLOW.getValue(),
+ Color.GRAY.getValue(),
+ Color.DKGRAY.getValue(),
+ Color.DKGRAY.getValue()
+ };
+
+
+ public static int getThumbColorForStates(int states){
+ switch (states){
+ case ComponentState.COMPONENT_STATE_EMPTY:
+ return ThumbColors[0];
+ case ComponentState.COMPONENT_STATE_CHECKED:
+ return ThumbColors[1];
+ default:
+ return defaultColor;
+
+ }
+ }
+
+ public static int getThumbColorForNextStates(int states){
+ switch (states){
+ case ComponentState.COMPONENT_STATE_EMPTY:
+ return ThumbColors[1];
+ case ComponentState.COMPONENT_STATE_CHECKED:
+ return ThumbColors[0];
+ default:
+ return defaultColor;
+
+ }
+ }
+
+ public static int getBlackColorForStates(int states){
+ switch (states){
+ case ComponentState.COMPONENT_STATE_EMPTY:
+ return BackColors[0];
+ case ComponentState.COMPONENT_STATE_CHECKED:
+ return BackColors[1];
+ default:
+ return defaultColor;
+
+ }
+ }
+
+ static int[] generateThumbColorWithTintColor(final int tintColor) {
+
+ ThumbColors = new int[]{
+ Color.BLACK.getValue(),Color.GREEN.getValue()
+ };
+ return ThumbColors;
+ }
+
+ static int[][] BackColorstates = new int[][]{
+ {ComponentState.COMPONENT_STATE_CHECKED},
+ {ComponentState.COMPONENT_STATE_EMPTY},
+ {ComponentState.COMPONENT_STATE_DISABLED},
+ {ComponentState.COMPONENT_STATE_PRESSED}
+ };
+
+
+ static int[] generateBackColorWithTintColor(final int tintColor) {
+
+ int[] colors = new int[]{
+ tintColor - 0xE1000000,
+ 0x10000000,
+ };
+ return colors;
+ }
+
+}
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/java/com/isoftstone/switchbutton/SwitchButton.java b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/java/com/isoftstone/switchbutton/SwitchButton.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c28d4982f3be91b2246a24573f7ee25654eac69
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/java/com/isoftstone/switchbutton/SwitchButton.java
@@ -0,0 +1,1360 @@
+package com.isoftstone.switchbutton;
+
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.*;
+import ohos.agp.components.element.Element;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.text.Layout;
+import ohos.agp.text.SimpleTextLayout;
+import ohos.agp.utils.*;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayManager;
+import ohos.app.Context;
+import ohos.global.resource.ResourceManager;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.multimodalinput.event.MmiPoint;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.util.Optional;
+
+
+/**
+ * SwitchButton
+ *
+ * @author kyleduo
+ * @since 2014-09-24
+ */
+
+@SuppressWarnings("unused")
+public class SwitchButton extends AbsButton implements AbsButton.CheckedStateChangedListener,Component.DrawTask{
+ private static HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x000115,"SwitchButton");
+ public static final float DEFAULT_THUMB_RANGE_RATIO = 1.8f;
+ public static final int DEFAULT_THUMB_SIZE_DP = 20;
+ public static final int DEFAULT_THUMB_MARGIN_DP = 2;
+ public static final int DEFAULT_ANIMATION_DURATION = 500;
+ public static final int DEFAULT_TINT_COLOR = 0x327FC2;
+
+
+ private static final int[] CHECKED_PRESSED_STATE = new int[]{ComponentState.COMPONENT_STATE_EMPTY,ComponentState.COMPONENT_STATE_CHECKED};
+ private static final int[] UNCHECKED_PRESSED_STATE = new int[]{ComponentState.COMPONENT_STATE_EMPTY,ComponentState.COMPONENT_STATE_CHECKED};
+
+ private Element mThumbDrawable,mThumbDrawable_on,mThumbDrawable_off,mBackDrawable,mBackDrawable_on,mBackDrawable_off;
+ private int[][] mBackColorStates, mThumbColorStates;
+ private int[] mBackColor, mThumbColor;
+ private float mThumbRadius, mBackRadius;
+ private RectFloat mThumbMargin;
+ private float mThumbRangeRatio;
+ private long mAnimationDuration;
+ // fade back drawable or color when dragging or animating
+ private boolean mFadeBack;
+ private int mTintColor;
+ private int mThumbWidth;
+ private int mThumbHeight;
+ private int mBackWidth = 100;
+ private int mBackHeight = 60;
+
+ private int mCurrThumbColor, mCurrBackColor, mNextBackColor, mOnTextColor, mOffTextColor;
+ private Element mCurrentBackDrawable, mNextBackDrawable;
+ private RectFloat mThumbRectF, mBackRectF, mSafeRectF, mTextOnRectF, mTextOffRectF;
+ private Paint mPaint;
+ // whether using Drawable for thumb or back
+ private boolean mIsThumbUseDrawable, mIsBackUseDrawable;
+ private boolean mDrawDebugRect = false;
+ private AnimatorValue mProgressAnimator;
+ // animation control
+ private float mProgress;
+ // temp position of thumb when dragging or animating
+ private RectFloat mPresentThumbRectF;
+ private float mStartX, mStartY, mLastX;
+ private int mTouchSlop;
+ private int mClickTimeout;
+ private Paint mRectPaint;
+ private CharSequence mTextOn;
+ private CharSequence mTextOff;
+ private Paint mTextPaint;
+ private Layout mOnLayout;
+ private Layout mOffLayout;
+ private float mTextWidth;
+ private float mTextHeight;
+ private int mTextThumbInset;
+ private int mTextExtra;
+ private int mTextAdjust;
+ // FIX #78,#85 : When restoring saved states, setChecked() called by super. So disable
+ // animation and event listening when restoring.
+ private boolean mRestoring = false;
+ private boolean mReady = false;
+ private boolean mCatch = false;
+ private UnsetPressedState mUnsetPressedState;
+ private boolean isCheck = false;
+ private int status = 0;
+ private final int STAUS_INIT = 0;
+ private final int STAUS_OFFTOON = 1;
+ private final int STAUS_ONTOOFF = 2;
+ private boolean isOnToOff = false;
+ private CheckedStateChangedListener mChildOnCheckedChangeListener;
+
+
+
+ public SwitchButton(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ HiLog.info(label,"SwitchButton3 init");
+// addDrawTask(this::onDraw);
+ init(attrSet);
+ onMeasure(getWidth(),getHeight());
+ }
+
+ private void init(AttrSet attrs) {
+ HiLog.info(label, "init start");
+// mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+// mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();
+ mTouchSlop = 22;
+ mClickTimeout = 164;
+ mPaint = new Paint();
+ mRectPaint = new Paint();
+ mRectPaint.setStyle(Paint.Style.STROKE_STYLE);
+ Optional display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
+ Point pt = new Point();
+ display.get().getSize(pt);
+ HiLog.info(label, "screenDensity:" + getResourceManager().getDeviceCapability().screenDensity);
+
+ mRectPaint.setStrokeWidth(getResourceManager().getDeviceCapability().screenDensity);
+
+ mTextPaint = mPaint;
+
+ mThumbRectF = new RectFloat();
+ mBackRectF = new RectFloat();
+ mSafeRectF = new RectFloat();
+ mThumbMargin = new RectFloat();
+ mTextOnRectF = new RectFloat();
+ mTextOffRectF = new RectFloat();
+
+// mProgressAnimator = AnimatorValue.ofFloat(0, 0).setDuration(DEFAULT_ANIMATION_DURATION);
+ mProgressAnimator = new AnimatorValue();
+ mProgressAnimator.setDuration(DEFAULT_ANIMATION_DURATION);
+ mProgressAnimator.setCurveType(Animator.CurveType.LINEAR);
+// mProgressAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
+ mProgressAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener(){
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ setProgress(v);
+ HiLog.info(label, "mProgressAnimator onUpdate:"+v);
+ }
+ });
+ mPresentThumbRectF = new RectFloat();
+
+ ResourceManager res = getResourceManager();
+ float density = res.getDeviceCapability().screenDensity;
+
+ Element thumbDrawable_on = null;
+ Element thumbDrawable_off = null;
+ int[] thumbColor = null;
+ float margin = density * DEFAULT_THUMB_MARGIN_DP;
+ float marginLeft = 0;
+ float marginRight = 0;
+ float marginTop = 0;
+ float marginBottom = 0;
+ float thumbWidth = 60;
+ float thumbHeight = 30;
+ float thumbRadius = 2;
+ float backRadius = 3;
+ Element backDrawable_on = null;
+ Element backDrawable_off = null;
+ int[] backColor = null;
+ float thumbRangeRatio = DEFAULT_THUMB_RANGE_RATIO;
+ int animationDuration = DEFAULT_ANIMATION_DURATION;
+ boolean fadeBack = true;
+ int tintColor = 0;
+ String textOn = null;
+ String textOff = null;
+ int textThumbInset = 0;
+ int textExtra = 0;
+ int textAdjust = 0;
+
+ HiLog.info(label, "解析xml数据");
+ HiLog.info(label, "解析xml数据:attrs"+attrs.toString());
+
+ thumbDrawable_on = attrs.getAttr("SwitchButton_ThumbDrawable_on").get().getElement();
+ HiLog.info(label, "thumbDrawable_on:");
+ thumbDrawable_off = attrs.getAttr("SwitchButton_ThumbDrawable_off").get().getElement();
+ HiLog.info(label, "thumbDrawable_off:");
+// thumbColor = ta.getColorStateList(R.styleable.SwitchButton_kswThumbColor);
+ margin = attrs.getAttr("SwitchButton_kswThumbMargin").get().getFloatValue();
+ HiLog.info(label, "margin:");
+ thumbWidth = attrs.getAttr("SwitchButton_kswThumbWidth").get().getFloatValue();
+ HiLog.info(label, "thumbWidth:" + thumbWidth);
+ thumbHeight = attrs.getAttr("SwitchButton_kswThumbHeight").get().getFloatValue();
+ HiLog.info(label, "thumbHeight:" + thumbHeight);
+ thumbRadius = attrs.getAttr("SwitchButton_kswThumbRadius").get().getFloatValue();
+ HiLog.info(label, "thumbRadius:" + thumbRadius);
+ backRadius = attrs.getAttr("SwitchButton_kswBackRadius").get().getFloatValue();
+ HiLog.info(label, "backRadius:" + backRadius);
+ backDrawable_on = attrs.getAttr("SwitchButton_BackDrawable_on").get().getElement();
+ backDrawable_off = attrs.getAttr("SwitchButton_BackDrawable_off").get().getElement();
+// backColor = ta.getColorStateList(R.styleable.SwitchButton_kswBackColor);
+ thumbRangeRatio = attrs.getAttr("SwitchButton_kswThumbRangeRatio").get().getFloatValue();
+ HiLog.info(label, "thumbRangeRatio:" + thumbRangeRatio);
+// animationDuration = attrs.getAttr("SwitchButton_animationDuration").get().getIntegerValue();
+// fadeBack = attrs.getAttr("SwitchButton_kswFadeBack").get().getBoolValue();
+ tintColor = attrs.getAttr("SwitchButton_tintColor").get().getColorValue().getValue();
+ HiLog.info(label, "tintColor:" + tintColor);
+ textOn = attrs.getAttr("SwitchButton_kswTextOn").get().getStringValue();
+ HiLog.info(label, "textOn:" + textOn);
+ textOff = attrs.getAttr("SwitchButton_kswTextOff").get().getStringValue();
+ HiLog.info(label, "textOff:" + textOff);
+// textThumbInset = attrs.getAttr("SwitchButton_kswTextThumbInset").get().getIntegerValue();
+// textExtra = attrs.getAttr("SwitchButton_kswTextExtra").get().getIntegerValue();
+// textThumbInset = attrs.getAttr("SwitchButton_kswTextAdjust").get().getIntegerValue();
+
+ mBackWidth = attrs.getAttr("SwitchButton_BackWidth").get().getIntegerValue();
+ mBackHeight = attrs.getAttr("SwitchButton_BackHeight").get().getIntegerValue();
+ setFocusable(1);
+ setClickable(true);
+
+ // text
+ mTextOn = textOn;
+ mTextOff = textOff;
+ mTextThumbInset = textThumbInset;
+ mTextExtra = textExtra;
+ mTextAdjust = textAdjust;
+
+ // thumb drawable and color
+ mThumbDrawable_on = thumbDrawable_on;
+ mThumbDrawable_off = thumbDrawable_off;
+ mThumbDrawable = thumbDrawable_off;
+ mThumbDrawable.setStateColorList(ColorUtils.ThumbColorstates, ColorUtils.ThumbColors);
+ mThumbColor = thumbColor;
+ mIsThumbUseDrawable = thumbDrawable_on != null && thumbDrawable_off != null ;
+ mTintColor = tintColor;
+ if (mTintColor == 0) {
+// mTintColor = getThemeAccentColorOrDefault(getContext(), DEFAULT_TINT_COLOR);
+ mTintColor = DEFAULT_TINT_COLOR;
+ }
+ if (!mIsThumbUseDrawable && mThumbColor == null) {
+ HiLog.info(label, "设置Thumb背景色");
+ mThumbColor = ColorUtils.generateThumbColorWithTintColor(mTintColor);
+ HiLog.info(label, "设置Thumb背景色mThumbColor:"+mThumbColor.length);
+ HiLog.info(label, "设置Thumb背景色成功");
+ mCurrThumbColor = ColorUtils.getThumbColorForStates(ComponentState.COMPONENT_STATE_EMPTY);
+ }
+
+ // thumbSize
+ mThumbWidth = ceil(thumbWidth);
+ mThumbHeight = ceil(thumbHeight);
+
+ // back drawable and color
+ mBackDrawable_on = backDrawable_on;
+ mBackDrawable_off = backDrawable_off;
+ mBackDrawable = mBackDrawable_off;
+ mBackColor = backColor;
+ mBackDrawable.setStateColorList(ColorUtils.BackColorstates, ColorUtils.BackColors);
+ mIsBackUseDrawable = backDrawable_on != null && backDrawable_off != null;
+ if (!mIsBackUseDrawable && mBackColor == null) {
+ HiLog.info(label, "设置Back背景色");
+ mBackColor = ColorUtils.generateBackColorWithTintColor(mTintColor);
+// mBackDrawable.setStateColorList(ColorUtils.BackColorstates, mBackColor);
+ HiLog.info(label, "设置Back背景色成功");
+ mCurrBackColor = ColorUtils.getBlackColorForStates(ComponentState.COMPONENT_STATE_EMPTY);
+ mNextBackColor = ColorUtils.getBlackColorForStates(ComponentState.COMPONENT_STATE_CHECKED);
+ HiLog.info(label,"onDraw:mCurrBackColor:"+mCurrBackColor);
+ HiLog.info(label,"onDraw:mNextBackColor:"+mNextBackColor);
+ }
+
+ // margin
+ HiLog.info(label, "定义mThumbMargin");
+ mThumbMargin.modify(marginLeft, marginTop, marginRight, marginBottom);
+ HiLog.info(label, "定义mThumbMargin成功");
+ // size & measure params must larger than 1
+ mThumbRangeRatio = mThumbMargin.getWidth() >= 0 ? Math.max(thumbRangeRatio, 1) : thumbRangeRatio;
+
+ mThumbRadius = thumbRadius;
+ mBackRadius = backRadius;
+ mAnimationDuration = animationDuration;
+ mFadeBack = fadeBack;
+
+// mProgressAnimator.setDuration(mAnimationDuration);
+
+ // sync checked status
+// if (isChecked()) {
+ setProgress(0);
+// }
+// setClickedListener(this::onClick);
+// setCheckedStateChangedListener(this::onCheckedChanged);
+ setTouchEventListener(this::onTouchEvent);
+// setClickedListener(this::onClick);
+
+ HiLog.info(label, "init finish");
+ }
+
+// private static int getThemeAccentColorOrDefault(Context context, @SuppressWarnings("SameParameterValue") int defaultColor) {
+// int colorAttr;
+// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+// colorAttr = android.R.attr.colorAccent;
+// } else {
+// //Get colorAccent defined for AppCompat
+// colorAttr = context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName());
+// }
+// TypedValue outValue = new TypedValue();
+// boolean resolved = context.getTheme().resolveAttribute(colorAttr, outValue, true);
+// return resolved ? outValue.data : defaultColor;
+// }
+
+ private Layout makeLayout(CharSequence text) {
+// return new StaticLayout(text, mTextPaint, (int) Math.ceil(Layout.getDesiredWidth(text, mTextPaint)), Layout.Alignment.ALIGN_CENTER, 1.f, 0, false);
+ HiLog.info(label,"创建开关文字控件:left:"+getLeft()+",top:"+getTop()+",right:"+getRight()+",bottom:"+getBottom()+",minwidth:"+getMinWidth());
+
+ return new SimpleTextLayout(text.toString(),mTextPaint,new Rect(),100);
+
+ }
+
+
+
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ /*
+ * ensure textLayout
+ */
+ HiLog.info(label,"widthMeasureSpec:"+widthMeasureSpec+",heightMeasureSpec:"+heightMeasureSpec);
+ if (mOnLayout == null && !TextTool.isNullOrEmpty(mTextOn)) {
+ mOnLayout = makeLayout(mTextOn);
+ }
+ if (mOffLayout == null && !TextTool.isNullOrEmpty(mTextOff)) {
+ mOffLayout = makeLayout(mTextOff);
+ }
+
+ float onWidth = mOnLayout != null ? mOnLayout.getWidth() : 0;
+ float offWidth = mOffLayout != null ? mOffLayout.getWidth() : 0;
+ HiLog.info(label,"onWidth :"+onWidth);
+ HiLog.info(label,"offWidth :"+offWidth);
+ if (onWidth != 0 || offWidth != 0) {
+ mTextWidth = Math.max(onWidth, offWidth);
+ } else {
+ mTextWidth = 0;
+ }
+
+ float onHeight = mOnLayout != null ? mOnLayout.getHeight() : 0;
+ float offHeight = mOffLayout != null ? mOffLayout.getHeight() : 0;
+ if (onHeight != 0 || offHeight != 0) {
+ mTextHeight = Math.max(onHeight, offHeight);
+ } else {
+ mTextHeight = 0;
+ }
+ HiLog.info(label,"mTextWidth :"+mTextWidth);
+ HiLog.info(label,"mTextHeight :"+mTextHeight);
+
+ setComponentSize(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
+ }
+
+ /**
+ * SwitchButton use this formula to determine the final size of thumb, background and itself.
+ *
+ * textWidth = max(onWidth, offWidth)
+ * thumbRange = thumbWidth * rangeRatio
+ * textExtraSpace = textWidth + textExtra - (moveRange - thumbWidth + max(thumbMargin.left, thumbMargin.right) + textThumbInset)
+ * backWidth = thumbRange + thumbMargin.left + thumbMargin.right + max(textExtraSpace, 0)
+ * contentSize = thumbRange + max(thumbMargin.left, 0) + max(thumbMargin.right, 0) + max(textExtraSpace, 0)
+ *
+ * @param widthMeasureSpec widthMeasureSpec
+ * @return measuredWidth
+ */
+ private int measureWidth(int widthMeasureSpec) {
+ int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ int measuredWidth = widthSize;
+
+ HiLog.info(label,"widthSize:"+widthSize+",widthMode:"+widthMode);
+ if (mThumbWidth == 0 && mIsThumbUseDrawable) {
+ mThumbWidth = mThumbDrawable.getWidth();
+ }
+
+ int moveRange;
+ int textWidth = ceil(mTextWidth);
+ // how much the background should extend to fit text.
+ int textExtraSpace;
+ int contentSize;
+
+ if (mThumbRangeRatio == 0) {
+ mThumbRangeRatio = DEFAULT_THUMB_RANGE_RATIO;
+ }
+
+ if (widthMode == MeasureSpec.PRECISE) {
+ contentSize = widthSize - getPaddingLeft() - getPaddingRight();
+
+ if (mThumbWidth != 0) {
+ moveRange = ceil(mThumbWidth * mThumbRangeRatio);
+ textExtraSpace = textWidth + mTextExtra - (moveRange - mThumbWidth + ceil(Math.max(mThumbMargin.left, mThumbMargin.right)));
+ mBackWidth = ceil(moveRange + mThumbMargin.left + mThumbMargin.right + Math.max(textExtraSpace, 0));
+ if (mBackWidth < 0) {
+ mThumbWidth = 0;
+ }
+ if (moveRange + Math.max(mThumbMargin.left, 0) + Math.max(mThumbMargin.right, 0) + Math.max(textExtraSpace, 0) > contentSize) {
+ mThumbWidth = 0;
+ }
+ }
+
+ if (mThumbWidth == 0) {
+ contentSize = widthSize - getPaddingLeft() - getPaddingRight();
+ moveRange = ceil(contentSize - Math.max(mThumbMargin.left, 0) - Math.max(mThumbMargin.right, 0));
+ if (moveRange < 0) {
+ mThumbWidth = 0;
+ mBackWidth = 0;
+ return measuredWidth;
+ }
+ mThumbWidth = ceil(moveRange / mThumbRangeRatio);
+ mBackWidth = ceil(moveRange + mThumbMargin.left + mThumbMargin.right);
+ if (mBackWidth < 0) {
+ mThumbWidth = 0;
+ mBackWidth = 0;
+ return measuredWidth;
+ }
+ textExtraSpace = textWidth + mTextExtra - (moveRange - mThumbWidth + ceil(Math.max(mThumbMargin.left, mThumbMargin.right)));
+ if (textExtraSpace > 0) {
+ // since backWidth is determined by view width, so we can only reduce thumbSize.
+ mThumbWidth = mThumbWidth - textExtraSpace;
+ }
+ if (mThumbWidth < 0) {
+ mThumbWidth = 0;
+ mBackWidth = 0;
+ return measuredWidth;
+ }
+ }
+ } else {
+ /*
+ If parent view want SwitchButton to determine it's size itself, we calculate the minimal
+ size of it's content. Further more, we ignore the limitation of widthSize since we want
+ to display SwitchButton in its actual size rather than compress the shape.
+ */
+ if (mThumbWidth == 0) {
+ /*
+ If thumbWidth is not set, use the default one.
+ */
+ mThumbWidth = ceil(getResourceManager().getDeviceCapability().screenDensity * DEFAULT_THUMB_SIZE_DP);
+ HiLog.info(label,"-----417-----mThumbWidth-----:"+mThumbWidth);
+ }
+ if (mThumbRangeRatio == 0) {
+ mThumbRangeRatio = DEFAULT_THUMB_RANGE_RATIO;
+ }
+ HiLog.info(label,"-----422-----mThumbWidth-----:"+mThumbWidth);
+ HiLog.info(label,"-----422-----mThumbRangeRatio-----:"+mThumbRangeRatio);
+ moveRange = ceil(mThumbWidth * mThumbRangeRatio);
+ textExtraSpace = ceil(textWidth + mTextExtra - (moveRange - mThumbWidth + Math.max(mThumbMargin.left, mThumbMargin.right) + mTextThumbInset));
+ HiLog.info(label,"-----425-----textExtraSpace-----:"+textExtraSpace);
+ mBackWidth = ceil(moveRange + mThumbMargin.left + mThumbMargin.right + Math.max(0, textExtraSpace));
+ HiLog.info(label,"-----427-----mBackWidth-----:"+mBackWidth);
+ if (mBackWidth < 0) {
+ mThumbWidth = 0;
+ mBackWidth = 0;
+ return measuredWidth;
+ }
+ contentSize = ceil(moveRange + Math.max(0, mThumbMargin.left) + Math.max(0, mThumbMargin.right) + Math.max(0, textExtraSpace));
+ HiLog.info(label,"-----434-----contentSize-----:"+contentSize);
+ measuredWidth = Math.max(contentSize, contentSize + getPaddingLeft() + getPaddingRight());
+ }
+ HiLog.info(label,"-----437-----measuredWidth-----:"+measuredWidth);
+ return measuredWidth;
+ }
+
+ private int measureHeight(int heightMeasureSpec) {
+ int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+ int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ int measuredHeight = heightSize;
+ HiLog.info(label,"heightSize:"+heightSize+",heightMode:"+heightMode);
+ if (mThumbHeight == 0 && mIsThumbUseDrawable) {
+ mThumbHeight = mThumbDrawable.getHeight();
+ }
+ int contentSize;
+ int textExtraSpace;
+ if (heightMode == MeasureSpec.PRECISE) {
+ if (mThumbHeight != 0) {
+ /*
+ If thumbHeight has been set, we calculate backHeight and check if there is enough room.
+ */
+ mBackHeight = ceil(mThumbHeight + mThumbMargin.top + mThumbMargin.bottom);
+ mBackHeight = ceil(Math.max(mBackHeight, mTextHeight));
+ if (mBackHeight + getPaddingTop() + getPaddingBottom() - Math.min(0, mThumbMargin.top) - Math.min(0, mThumbMargin.bottom) > heightSize) {
+ // No enough room, we set thumbHeight to zero to calculate these value again.
+ mThumbHeight = 0;
+ }
+ }
+
+ if (mThumbHeight == 0) {
+ mBackHeight = ceil(heightSize - getPaddingTop() - getPaddingBottom() + Math.min(0, mThumbMargin.top) + Math.min(0, mThumbMargin.bottom));
+ if (mBackHeight < 0) {
+ mBackHeight = 0;
+ mThumbHeight = 0;
+ return measuredHeight;
+ }
+ mThumbHeight = ceil(mBackHeight - mThumbMargin.top - mThumbMargin.bottom);
+ }
+ if (mThumbHeight < 0) {
+ mBackHeight = 0;
+ mThumbHeight = 0;
+ return measuredHeight;
+ }
+ } else {
+ if (mThumbHeight == 0) {
+ mThumbHeight = ceil(getResourceManager().getDeviceCapability().screenDensity * DEFAULT_THUMB_SIZE_DP);
+ }
+ mBackHeight = ceil(mThumbHeight + mThumbMargin.top + mThumbMargin.bottom);
+ if (mBackHeight < 0) {
+ mBackHeight = 0;
+ mThumbHeight = 0;
+ return measuredHeight;
+ }
+ textExtraSpace = ceil(mTextHeight - mBackHeight);
+ if (textExtraSpace > 0) {
+ mBackHeight += textExtraSpace;
+ mThumbHeight += textExtraSpace;
+ }
+ contentSize = Math.max(mThumbHeight, mBackHeight);
+
+ measuredHeight = Math.max(contentSize, contentSize + getPaddingTop() + getPaddingBottom());
+ measuredHeight = Math.max(measuredHeight, getMinHeight());
+ }
+
+ return measuredHeight;
+ }
+//
+// @Override
+// protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+// super.onSizeChanged(w, h, oldw, oldh);
+// if (w != oldw || h != oldh) {
+// setup();
+// }
+// }
+
+ private int ceil(double dimen) {
+ return (int) Math.ceil(dimen);
+ }
+
+ /**
+ * set up the rect of back and thumb
+ */
+ private void setup() {
+ if (mThumbWidth == 0 || mThumbHeight == 0 || mBackWidth == 0 || mBackHeight == 0) {
+ HiLog.info(label,"setup:return");
+ return;
+ }
+
+ if (mThumbRadius == -1) {
+ mThumbRadius = Math.min(mThumbWidth, mThumbHeight) / 2f;
+ }
+ if (mBackRadius == -1) {
+ mBackRadius = Math.min(mBackWidth, mBackHeight) / 2f;
+ }
+
+ HiLog.info(label,"mThumbRadius:"+mThumbRadius);
+ HiLog.info(label,"mBackRadius:"+mBackRadius);
+ HiLog.info(label,"getPaddingLeft:"+getPaddingLeft());
+ HiLog.info(label,"getPaddingRight:"+getPaddingRight());
+ int contentWidth = getWidth() - getPaddingLeft() - getPaddingRight();
+ int contentHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+ HiLog.info(label,"contentWidth:"+contentWidth);
+ HiLog.info(label,"contentWidth:"+contentWidth);
+ // max range of drawing content, when thumbMargin is negative, drawing range is larger than backWidth
+ int drawingWidth = ceil(mBackWidth - Math.min(0, mThumbMargin.left) - Math.min(0, mThumbMargin.right));
+ int drawingHeight = ceil(mBackHeight - Math.min(0, mThumbMargin.top) - Math.min(0, mThumbMargin.bottom));
+ HiLog.info(label,"drawingWidth:"+drawingWidth);
+ HiLog.info(label,"drawingHeight:"+drawingHeight);
+ float thumbTop;
+ if (contentHeight <= drawingHeight) {
+ thumbTop = getPaddingTop() + Math.max(0, mThumbMargin.top);
+ } else {
+ // center vertical in content area
+ thumbTop = getPaddingTop() + Math.max(0, mThumbMargin.top) + (contentHeight - drawingHeight + 1) / 2f;
+ }
+ HiLog.info(label,"thumbTop:"+thumbTop);
+ float thumbLeft;
+ if (contentWidth <= mBackWidth) {
+ thumbLeft = getPaddingLeft() + Math.max(0, mThumbMargin.left);
+ } else {
+ thumbLeft = getPaddingLeft() + Math.max(0, mThumbMargin.left) + (contentWidth - drawingWidth + 1) / 2f;
+ }
+ HiLog.info(label,"thumbLeft:"+thumbLeft);
+
+ mThumbRectF.modify(thumbLeft, thumbTop, thumbLeft + mThumbWidth, thumbTop + mThumbHeight);
+ HiLog.info(label,"设置mThumbRectF:");
+ float backLeft = mThumbRectF.left - mThumbMargin.left;
+ mBackRectF.modify(backLeft,
+ mThumbRectF.top - mThumbMargin.top,
+ backLeft + mBackWidth,
+ mThumbRectF.top - mThumbMargin.top + mBackHeight);
+ HiLog.info(label,"设置mBackRectF:");
+ mSafeRectF.modify(mThumbRectF.left, 0, mBackRectF.right - mThumbMargin.right - mThumbRectF.getWidth(), 0);
+ HiLog.info(label,"设置mSafeRectF:");
+ float minBackRadius = Math.min(mBackRectF.getWidth(), mBackRectF.getHeight()) / 2.f;
+ mBackRadius = Math.min(minBackRadius, mBackRadius);
+
+ if (mBackDrawable != null) {
+ mBackDrawable.setBounds((int) mBackRectF.left, (int) mBackRectF.top, ceil(mBackRectF.right), ceil(mBackRectF.bottom));
+ }
+
+ if (mOnLayout != null) {
+ float onLeft = mBackRectF.left + (mBackRectF.getWidth() + mTextThumbInset - mThumbWidth - mThumbMargin.right - mOnLayout.getWidth()) / 2f - mTextAdjust;
+ float onTop = mBackRectF.top + (mBackRectF.getHeight() - mOnLayout.getHeight()) / 2;
+ mTextOnRectF.modify(onLeft, onTop, onLeft + mOnLayout.getWidth(), onTop + mOnLayout.getHeight());
+ }
+
+ if (mOffLayout != null) {
+ float offLeft = mBackRectF.right - (mBackRectF.getWidth() + mTextThumbInset - mThumbWidth - mThumbMargin.left - mOffLayout.getWidth()) / 2f - mOffLayout.getWidth() + mTextAdjust;
+ float offTop = mBackRectF.top + (mBackRectF.getHeight() - mOffLayout.getHeight()) / 2;
+ mTextOffRectF.modify(offLeft, offTop, offLeft + mOffLayout.getWidth(), offTop + mOffLayout.getHeight());
+ }
+
+ mReady = true;
+ }
+
+
+ @Override
+ public void invalidate() {
+ addDrawTask(this::onDraw);
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas){
+ float progress;
+ HiLog.info(label,"onDraw:isCheck"+isCheck);
+ HiLog.info(label,"onDraw:isOnToOff"+isOnToOff);
+ HiLog.info(label,"onDraw:mProgress:"+mProgress);
+ if(isOnToOff){
+ progress = mProgress;
+ }else{
+ progress = mProgress;
+ }
+ HiLog.info(label,"onDraw:progress:"+progress);
+ HiLog.info(label,"onDraw");
+ if (!mReady) {
+ HiLog.info(label,"onDraw:setup");
+ setup();
+ }
+ if (!mReady) {
+ HiLog.info(label,"onDraw:return");
+ return;
+ }
+
+ // fade back
+ if (mIsBackUseDrawable) {
+ if (mFadeBack && mCurrentBackDrawable != null && mNextBackDrawable != null) {
+ // fix #75, 70%A + 30%B != 30%B + 70%A, order matters when mix two layer of different alpha.
+ // So make sure the order of on/off layers never change during slide from one endpoint to another.
+ Element below = isChecked() ? mCurrentBackDrawable : mNextBackDrawable;
+ Element above = isChecked() ? mNextBackDrawable : mCurrentBackDrawable;
+
+ int alpha = (int) (255 * getProgress());
+ below.setAlpha(alpha);
+ below.drawToCanvas(canvas);
+ alpha = 255 - alpha;
+ above.setAlpha(alpha);
+ above.drawToCanvas(canvas);
+ } else {
+ HiLog.info(label,"onDraw:619");
+ mBackDrawable.setAlpha(255);
+ mBackDrawable.drawToCanvas(canvas);
+ }
+ } else {
+ if (mFadeBack) {
+ HiLog.info(label,"onDraw:624");
+ int alpha;
+ int colorAlpha;
+
+ // fix #75
+ int belowColor = isChecked() ? mCurrBackColor : mNextBackColor;
+ int aboveColor = isChecked() ? mNextBackColor : mCurrBackColor;
+ HiLog.info(label,"onDraw:mCurrBackColor:"+mCurrBackColor);
+ HiLog.info(label,"onDraw:mNextBackColor:"+mNextBackColor);
+ HiLog.info(label,"onDraw:belowColor:"+belowColor);
+ HiLog.info(label,"onDraw:aboveColor:"+aboveColor);
+ // 当前背景色
+ alpha = (int) (255 * getProgress());
+ colorAlpha = Color.alpha(belowColor);
+ colorAlpha = colorAlpha * alpha / 255;
+ RgbColor rgbColor = new RgbColor(belowColor);
+// mPaint.setARGB(colorAlpha, Color.red(belowColor), Color.green(belowColor), Color.blue(belowColor));
+ Color color = new Color(Color.argb(colorAlpha, rgbColor.getRed(), rgbColor.getGreen(), rgbColor.getBlue()));
+// Color color = new Color(belowColor);
+// HiLog.info(label,"onDraw:color:"+color.getValue());
+ mPaint.setColor(color);
+ HiLog.info(label,"onDraw:color:"+color);
+ canvas.drawRoundRect(mBackRectF, mBackRadius, mBackRadius, mPaint);
+
+ // next back
+ alpha = 255 - alpha;
+ colorAlpha = Color.alpha(aboveColor);
+ colorAlpha = colorAlpha * alpha / 255;
+// mPaint.setARGB(colorAlpha, Color.red(aboveColor), Color.green(aboveColor), Color.blue(aboveColor));
+ RgbColor rgbColor2 = new RgbColor(aboveColor);
+ Color color2 = new Color(Color.argb(colorAlpha, rgbColor2.getRed(), rgbColor2.getGreen(), rgbColor2.getBlue()));
+// Color color2 = new Color(aboveColor);
+ mPaint.setColor(color2);
+ HiLog.info(label,"onDraw:color2:"+color2);
+ canvas.drawRoundRect(mBackRectF, mBackRadius, mBackRadius, mPaint);
+
+ mPaint.setAlpha(255);
+ } else {
+ HiLog.info(label,"onDraw:653");
+ mPaint.setColor(new Color(mCurrBackColor));
+ canvas.drawRoundRect(mBackRectF, mBackRadius, mBackRadius, mPaint);
+ }
+ }
+
+ //text
+ Layout switchText =progress > 0.5 ? mOnLayout : mOffLayout;
+ HiLog.info(label,"onDraw:switchText:"+switchText.getHeight()+",width:"+switchText.getWidth());
+ RectFloat textRectF = progress > 0.5 ? mTextOnRectF : mTextOffRectF;
+ if (switchText != null && textRectF != null) {
+ int alpha = (int) (255 * (progress >= 0.75 ? progress * 4 - 3 : progress < 0.25 ? 1 - progress * 4 : 0));
+ int textColor = progress > 0.5 ? mOnTextColor : mOffTextColor;
+ int colorAlpha = Color.alpha(textColor);
+ colorAlpha = colorAlpha * alpha / 255;
+
+ RgbColor textColorRgb = new RgbColor(textColor);
+ Color color2 = new Color(Color.argb(colorAlpha, textColorRgb.getRed(), textColorRgb.getGreen(), textColorRgb.getBlue()));
+ mTextPaint.setColor(color2);
+
+ canvas.save();
+ canvas.translate(textRectF.left, textRectF.top);
+ switchText.drawText(canvas);
+ HiLog.info(label,switchText.toString());
+ canvas.restore();
+ }
+
+ // thumb滑块
+ mPresentThumbRectF.modify(mThumbRectF);
+ HiLog.info(label,"onDraw:设置mPresentThumbRectF:");
+ setOffsetOfRectF(mPresentThumbRectF,progress * mSafeRectF.getWidth(), 0);
+ HiLog.info(label,"onDraw:设置mPresentThumbRectF成功:");
+ if (mIsThumbUseDrawable) {
+ HiLog.info(label,"onDraw:mThumbDrawable:");
+ mThumbDrawable.setBounds((int) mPresentThumbRectF.left, (int) mPresentThumbRectF.top, ceil(mPresentThumbRectF.right), ceil(mPresentThumbRectF.bottom));
+ mThumbDrawable.drawToCanvas(canvas);
+ } else {
+ mPaint.setColor(new Color(mCurrThumbColor));
+ canvas.drawRoundRect(mPresentThumbRectF, mThumbRadius, mThumbRadius, mPaint);
+ HiLog.info(label,"onDraw:drawRoundRect:");
+ }
+
+ if (mDrawDebugRect) {
+ mRectPaint.setColor(new Color(Color.getIntColor("#AA0000")));
+ canvas.drawRect(mBackRectF, mRectPaint);
+ mRectPaint.setColor(new Color(Color.getIntColor("#0000FF")));
+ canvas.drawRect(mPresentThumbRectF, mRectPaint);
+ mRectPaint.setColor(new Color(Color.getIntColor("#000000")));
+ Point startPoint = new Point(mSafeRectF.left, mThumbRectF.top);
+ Point endPoint = new Point( mSafeRectF.right, mThumbRectF.top);
+ canvas.drawLine(startPoint,endPoint, mRectPaint);
+ mRectPaint.setColor(new Color(Color.getIntColor("#00CC00")));
+ canvas.drawRect(getProgress() > 0.5 ? mTextOnRectF : mTextOffRectF, mRectPaint);
+ }
+ }
+
+ private RectFloat setOffsetOfRectF(RectFloat rectFloat,float offsetX,float offsetY){
+ float left = rectFloat.left + offsetX;
+ float right = rectFloat.right + offsetX;
+ float top = rectFloat.top + offsetY;
+ float bottom = rectFloat.bottom + offsetY;
+ rectFloat.modify(left,top,right,bottom);
+ return rectFloat;
+ }
+
+
+ protected void drawableStateChanged(int states) {
+ mReady = false;
+ if (!mIsThumbUseDrawable && mThumbColor != null) {
+ mCurrThumbColor = ColorUtils.getThumbColorForStates(states);
+ HiLog.info(label, "修改滑块颜色:"+mCurrThumbColor);
+ } else {
+ if(getProgress() >= 0.5){
+ mThumbDrawable = mThumbDrawable_on;
+ }else{
+ mThumbDrawable = mThumbDrawable_off;
+ }
+
+ }
+
+ int[] nextState = isChecked() ? UNCHECKED_PRESSED_STATE : CHECKED_PRESSED_STATE;
+
+ if (!mIsBackUseDrawable && mBackColor != null) {
+ mCurrBackColor = ColorUtils.getThumbColorForStates(states);
+ mNextBackColor = ColorUtils.getThumbColorForNextStates(states);
+ HiLog.info(label, "修改轨迹颜色:"+mNextBackColor);
+ } else {
+ if(getProgress() >= 0.5){
+ mBackDrawable = mBackDrawable_on;
+ }else{
+ mBackDrawable = mBackDrawable_off;
+ }
+ }
+ }
+
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ {
+ int action = touchEvent.getAction();
+ MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
+ float deltaX = point.getX() - mStartX;
+ float deltaY = point.getY() - mStartY;
+
+ switch (action) {
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ mStartX = point.getX();
+ mStartY = point.getY();
+ mLastX = mStartX;
+ setPressState(true);
+ break;
+
+ case TouchEvent.POINT_MOVE:
+ float x = point.getX();
+ drawableStateChanged(isCheck?ComponentState.COMPONENT_STATE_CHECKED:ComponentState.COMPONENT_STATE_EMPTY);
+ setProgress(getProgress() + (x - mLastX) / mSafeRectF.getWidth());
+ mLastX = x;
+ if (!mCatch && (Math.abs(deltaX) > mTouchSlop / 2f || Math.abs(deltaY) > mTouchSlop / 2f)) {
+ if (deltaY == 0 || Math.abs(deltaX) > Math.abs(deltaY)) {
+ catchView();
+ } else if (Math.abs(deltaY) > Math.abs(deltaX)) {
+ return false;
+ }
+ }
+ break;
+
+ case TouchEvent.CANCEL:
+ case TouchEvent.PRIMARY_POINT_UP:
+ mCatch = false;
+ float time = touchEvent.getOccurredTime() - touchEvent.getStartTime();
+ if (Math.abs(deltaX) < mTouchSlop && Math.abs(deltaY) < mTouchSlop && time < mClickTimeout) {
+ HiLog.info(label,"Log_onTouchEvent simulateClick");
+ simulateClick();
+ } else {
+ boolean nextStatus = getStatusBasedOnPos();
+ if (nextStatus != isChecked()) {
+ setChecked(nextStatus);
+ }
+ else {
+ setProgress(nextStatus?1:0);
+ }
+ }
+ if (isPressed()) {
+ if (mUnsetPressedState == null) {
+ mUnsetPressedState = new UnsetPressedState();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return true;
+ }
+ }
+
+
+
+ /**
+ * return the status based on position of thumb
+ *
+ * @return whether checked or not
+ */
+ private boolean getStatusBasedOnPos() {
+ return getProgress() > 0.5f;
+ }
+
+ @Override
+ public boolean simulateClick() {
+ HiLog.info(label,"simulateClick");
+ setChecked(!isCheck);
+ return true;
+ }
+
+ /**
+ * processing animation
+ *
+ * @param checked checked or unChecked
+ */
+ protected void animateToState(boolean checked) {
+ if (mProgressAnimator == null) {
+ return;
+ }
+ if (mProgressAnimator.isRunning()) {
+ mProgressAnimator.cancel();
+ }
+ mProgressAnimator.setDuration(mAnimationDuration);
+ mProgressAnimator.start();
+ }
+
+ private void catchView() {
+ ComponentParent parent = getComponentParent();
+ if (parent != null) {
+// parent.requestDisallowInterceptTouchEvent(true);
+ }
+ mCatch = true;
+ }
+
+ @Override
+ public void setChecked(final boolean checked) {
+ // animate before super.setChecked() become user may call setChecked again in OnCheckedChangedListener
+ HiLog.info(label,"checked:"+checked);
+// if (isChecked() != checked) {
+// animateToState(checked);
+// }
+ isCheck = checked;
+ if(mChildOnCheckedChangeListener != null){
+ mChildOnCheckedChangeListener.onCheckedChanged(this,isCheck);
+ }
+ setProgress(isCheck?1:0);
+ drawableStateChanged(isCheck?ComponentState.COMPONENT_STATE_CHECKED:ComponentState.COMPONENT_STATE_EMPTY);
+// if(isCheck){
+// isOnToOff = false;
+// }else{
+// isOnToOff = true;
+// }
+// if (mRestoring) {
+// setCheckedImmediatelyNoEvent(checked);
+// } else {
+// super.setChecked(checked);
+// }
+ }
+
+ public boolean isChecked() {
+ return isCheck;
+ }
+
+ public void setCheckedNoEvent(final boolean checked) {
+ if (mChildOnCheckedChangeListener == null) {
+ setChecked(checked);
+ } else {
+ setCheckedStateChangedListener(null);
+ setChecked(checked);
+ setCheckedStateChangedListener(mChildOnCheckedChangeListener);
+ }
+ }
+
+ public void setCheckedImmediatelyNoEvent(boolean checked) {
+ if (mChildOnCheckedChangeListener == null) {
+ setCheckedImmediately(checked);
+ } else {
+ setCheckedStateChangedListener(null);
+ setCheckedImmediately(checked);
+ setCheckedStateChangedListener(mChildOnCheckedChangeListener);
+ }
+ }
+
+ public void setCheckedImmediately(boolean checked) {
+ setChecked(checked);
+ if (mProgressAnimator != null && mProgressAnimator.isRunning()) {
+ mProgressAnimator.cancel();
+ }
+ setProgress(checked ? 1 : 0);
+ invalidate();
+ }
+
+ private float getProgress() {
+ return mProgress;
+ }
+
+ private void setProgress(final float progress) {
+ float tempProgress = progress;
+ if (tempProgress > 1) {
+ tempProgress = 1;
+ } else if (tempProgress < 0) {
+ tempProgress = 0;
+ }
+ this.mProgress = tempProgress;
+ HiLog.info(label,"progress:"+mProgress);
+ invalidate();
+ }
+
+
+ public void toggleImmediately() {
+ setCheckedImmediately(!isChecked());
+ }
+
+ public void toggleNoEvent() {
+ if (mChildOnCheckedChangeListener == null) {
+ toggle();
+ } else {
+ setCheckedStateChangedListener(null);
+ toggle();
+ setCheckedStateChangedListener(mChildOnCheckedChangeListener);
+ }
+ }
+
+ public void toggle() {
+ setChecked(!isChecked());
+ }
+
+ public void toggleImmediatelyNoEvent() {
+ if (mChildOnCheckedChangeListener == null) {
+ toggleImmediately();
+ } else {
+ super.setCheckedStateChangedListener(null);
+ toggleImmediately();
+ super.setCheckedStateChangedListener(mChildOnCheckedChangeListener);
+ }
+ }
+
+ @Override
+ public void setCheckedStateChangedListener(CheckedStateChangedListener onCheckedChangeListener) {
+// super.setCheckedStateChangedListener(onCheckedChangeListener);
+ mChildOnCheckedChangeListener = onCheckedChangeListener;
+ }
+
+
+// private void setDrawableState(Element element) {
+// if (drawable != null) {
+// int[] myDrawableState = getDrawableState();
+// drawable.setState(myDrawableState);
+// invalidate();
+// }
+// }
+
+ public boolean isDrawDebugRect() {
+ return mDrawDebugRect;
+ }
+
+ public void setDrawDebugRect(boolean drawDebugRect) {
+ mDrawDebugRect = drawDebugRect;
+ invalidate();
+ }
+
+ public long getAnimationDuration() {
+ return mAnimationDuration;
+ }
+
+ public void setAnimationDuration(long animationDuration) {
+ mAnimationDuration = animationDuration;
+ }
+
+ public Element getThumbDrawable() {
+ return mThumbDrawable;
+ }
+
+ public void setThumbDrawable(Element thumbDrawable) {
+ mThumbDrawable = thumbDrawable;
+ mIsThumbUseDrawable = mThumbDrawable != null;
+// refreshDrawableState();
+ mReady = false;
+// requestLayout();
+ invalidate();
+ }
+
+// public void setThumbDrawableRes(int thumbDrawableRes) {
+// setThumbDrawable(getDrawableCompat(getContext(), thumbDrawableRes));
+// }
+
+ public Element getBackDrawable() {
+ return mBackDrawable;
+ }
+
+ public void setBackDrawable(Element backDrawable) {
+ mBackDrawable = backDrawable;
+ mIsBackUseDrawable = mBackDrawable != null;
+// refreshDrawableState();
+ mReady = false;
+// requestLayout();
+ invalidate();
+ }
+
+// public void setBackDrawableRes(int backDrawableRes) {
+// setBackDrawable(getDrawableCompat(getContext(), backDrawableRes));
+// }
+
+ public int[] getBackColor() {
+ return mBackColor;
+ }
+
+ public void setBackColor(int[] backColor) {
+ mBackColor = backColor;
+ if (mBackColor != null) {
+ setBackDrawable(null);
+ }
+ invalidate();
+ }
+
+ public void setBackColorRes(int backColorRes) {
+ setBackColor(ColorUtils.generateBackColorWithTintColor(backColorRes));
+ }
+
+ public int[] getThumbColor() {
+ return mThumbColor;
+ }
+
+ public void setThumbColor(int[] thumbColor) {
+ mThumbColor = thumbColor;
+ if (mThumbColor != null) {
+ setThumbDrawable(null);
+ }
+ invalidate();
+ }
+
+// public void setThumbColorRes(int thumbColorRes) {
+// setThumbColor(getColorStateListCompat(getContext(), thumbColorRes));
+// }
+
+ public float getThumbRangeRatio() {
+ return mThumbRangeRatio;
+ }
+
+ public void setThumbRangeRatio(float thumbRangeRatio) {
+ mThumbRangeRatio = thumbRangeRatio;
+ // We need to mark "ready" to false since requestLayout may not cause size changed.
+ mReady = false;
+// requestLayout();
+ }
+
+ public RectFloat getThumbMargin() {
+ return mThumbMargin;
+ }
+
+ public void setThumbMargin(RectFloat thumbMargin) {
+ if (thumbMargin == null) {
+ setThumbMargin(0, 0, 0, 0);
+ } else {
+ setThumbMargin(thumbMargin.left, thumbMargin.top, thumbMargin.right, thumbMargin.bottom);
+ }
+ }
+
+ public void setThumbMargin(float left, float top, float right, float bottom) {
+ mThumbMargin.modify(left, top, right, bottom);
+ mReady = false;
+// requestLayout();
+ }
+
+ public void setThumbSize(int width, int height) {
+ mThumbWidth = width;
+ mThumbHeight = height;
+ mReady = false;
+// requestLayout();
+ }
+
+ public int getThumbWidth() {
+ return mThumbWidth;
+ }
+
+ public int getThumbHeight() {
+ return mThumbHeight;
+ }
+
+ public float getThumbRadius() {
+ return mThumbRadius;
+ }
+
+ public void setThumbRadius(float thumbRadius) {
+ mThumbRadius = thumbRadius;
+ if (!mIsThumbUseDrawable) {
+ invalidate();
+ }
+ }
+
+ public Point getBackSizeF() {
+ return new Point(mBackRectF.getWidth(), mBackRectF.getHeight());
+ }
+
+ public float getBackRadius() {
+ return mBackRadius;
+ }
+
+ public void setBackRadius(float backRadius) {
+ mBackRadius = backRadius;
+ if (!mIsBackUseDrawable) {
+ invalidate();
+ }
+ }
+
+ public boolean isFadeBack() {
+ return mFadeBack;
+ }
+
+ public void setFadeBack(boolean fadeBack) {
+ mFadeBack = fadeBack;
+ }
+
+ public int getTintColor() {
+ return mTintColor;
+ }
+
+ public void setTintColor(@SuppressWarnings("SameParameterValue") int tintColor) {
+ mTintColor = tintColor;
+ mThumbColor = ColorUtils.generateThumbColorWithTintColor(mTintColor);
+ mBackColor = ColorUtils.generateBackColorWithTintColor(mTintColor);
+ mIsBackUseDrawable = false;
+ mIsThumbUseDrawable = false;
+ // call this method to refresh color states
+// refreshDrawableState();
+ invalidate();
+ }
+
+ public void setText(CharSequence onText, CharSequence offText) {
+ mTextOn = onText;
+ mTextOff = offText;
+
+ mOnLayout = null;
+ mOffLayout = null;
+
+ mReady = false;
+// requestLayout();
+ invalidate();
+ }
+
+ public CharSequence getTextOn() {
+ return mTextOn;
+ }
+
+ public CharSequence getTextOff() {
+ return mTextOff;
+ }
+
+ public void setTextThumbInset(int textThumbInset) {
+ mTextThumbInset = textThumbInset;
+ mReady = false;
+// requestLayout();
+ invalidate();
+ }
+
+ public void setTextExtra(int textExtra) {
+ mTextExtra = textExtra;
+ mReady = false;
+// requestLayout();
+ invalidate();
+ }
+
+ public void setTextAdjust(int textAdjust) {
+ mTextAdjust = textAdjust;
+ mReady = false;
+// requestLayout();
+ invalidate();
+ }
+
+// @Override
+// public void onClick(Component component) {
+// HiLog.info(label,"onClick");
+// drawableStateChanged();
+//
+// }
+
+
+// @Override
+// public void onClick(Component component) {
+// HiLog.info(label,"onClick");
+//// setProgress(0);
+// setChecked(!isCheck);
+// }
+
+ @Override
+ public boolean isClickable() {
+ HiLog.info(label,"isClickable"+isChecked());
+ return super.isClickable();
+ }
+
+
+
+ @Override
+ public void onCheckedChanged(AbsButton absButton, boolean b) {
+ HiLog.info(label,"onCheckedChanged");
+ }
+
+
+ // @Override
+// public Parcelable onSaveInstanceState() {
+// Parcelable superState = super.onSaveInstanceState();
+// SavedState ss = new SavedState(superState);
+// ss.onText = mTextOn;
+// ss.offText = mTextOff;
+// return ss;
+// }
+//
+// @Override
+// public void onRestoreInstanceState(Parcelable state) {
+// SavedState ss = (SavedState) state;
+// setText(ss.onText, ss.offText);
+// mRestoring = true;
+// super.onRestoreInstanceState(ss.getSuperState());
+// mRestoring = false;
+// }
+
+// /**
+// * Copied from compat library
+// *
+// * @param context context
+// * @param id id
+// * @return Drawable
+// */
+// private Element getDrawableCompat(Context context, int id) {
+// final int version = Build.VERSION.SDK_INT;
+// if (version >= 21) {
+// return context.getDrawable(id);
+// } else {
+// //noinspection deprecation
+// return context.getResources().getDrawable(id);
+// }
+// ohos.global.resource.ResourceManager resManager = getResourceManager();
+// try {
+// Element element = resManager.getElement(id);
+// } catch (IOException e) {
+// e.printStackTrace();
+// } catch (NotExistException e) {
+// e.printStackTrace();
+// } catch (WrongTypeException e) {
+// e.printStackTrace();
+// }
+//
+// }
+
+// /**
+// * Copied from compat library
+// *
+// * @param context context
+// * @param id id
+// * @return ColorStateList
+// */
+// private int[] getColorStateListCompat(Context context, int id) {
+// final int version = Build.VERSION.SDK_INT;
+// if (version >= 23) {
+// return context.getColorStateList(id);
+// } else {
+// //noinspection deprecation
+// return context.getResources().getColorStateList(id);
+// }
+//
+//
+// }
+
+// static class SavedState extends BaseSavedState {
+// CharSequence onText;
+// CharSequence offText;
+//
+// SavedState(Sequenceable superState) {
+// super(superState);
+// }
+//
+// private SavedState(Parcel in) {
+// super(in);
+// onText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+// offText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+// }
+//
+// @Override
+// public void writeToParcel(Parcel out, int flags) {
+// super.writeToParcel(out, flags);
+// TextUtils.writeToParcel(onText, out, flags);
+// TextUtils.writeToParcel(offText, out, flags);
+// }
+//
+// public static final Parcelable.Creator CREATOR
+// = new Parcelable.Creator() {
+// public SavedState createFromParcel(Parcel in) {
+// return new SavedState(in);
+// }
+//
+// public SavedState[] newArray(int size) {
+// return new SavedState[size];
+// }
+// };
+// }
+
+ private final class UnsetPressedState implements Runnable {
+ @Override
+ public void run() {
+ setPressState(false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/element/color.json b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..dcadd0d004117c2ea9bfb440bc6712382d68135c
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/element/color.json
@@ -0,0 +1,32 @@
+{
+ "color":[
+ {
+ "name":"ripple_normal",
+ "value":"#1E000000"
+ },
+ {
+ "name":"ripple_checked",
+ "value":"#33019285"
+ },
+ {
+ "name":"solid_shadow",
+ "value":"#33000000"
+ },
+ {
+ "name":"solid_normal",
+ "value":"#ECECEC"
+ },
+ {
+ "name":"solid_checked",
+ "value":"#019285"
+ },
+ {
+ "name":"solid_disable",
+ "value":"#FFFFFF"
+ },
+ {
+ "name":"solid_checked_disable",
+ "value":"#aaaaaa"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/element/string.json b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..95edab40ce9b866ad8af99ab3b3d25e0f752a0c1
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "SwitchButton"
+ }
+ ]
+}
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_back_off.xml b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_back_off.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0eaecb65b9f5e8ec01a0d58041b5b6aea139dba0
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_back_off.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_back_on.xml b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_back_on.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61d321928e92541e74743def956ba5f364d5280c
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_back_on.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_thumb_off.xml b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_thumb_off.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8cea2e3cd004af1903beb3d94285a609bb2f141c
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_thumb_off.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_thumb_on.xml b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_thumb_on.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f620d778a3c53a03175e685618adf619c0f94e07
--- /dev/null
+++ b/010.switchButton_OpenHarmony-master/code/switchbutton/src/main/resources/base/graphic/button_thumb_on.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git "a/010.switchButton_OpenHarmony-master/doc/010.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204SwitchButton\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/010.switchButton_OpenHarmony-master/doc/010.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204SwitchButton\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..dd02903f701d6f7c22785d552f7941cc73c02bfb
Binary files /dev/null and "b/010.switchButton_OpenHarmony-master/doc/010.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204SwitchButton\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/011.NScrolling_OpenHarmony-master/.gitignore b/011.NScrolling_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/011.NScrolling_OpenHarmony-master/.idea/.gitignore b/011.NScrolling_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/011.NScrolling_OpenHarmony-master/.idea/compiler.xml b/011.NScrolling_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/.idea/gradle.xml b/011.NScrolling_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..84d292581c8d0fd427aea831bb54bddea83e80b7
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/.idea/inspectionProfiles/Project_Default.xml b/011.NScrolling_OpenHarmony-master/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f4be559210aa9468e22b42975470411b96f7c3ba
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/.idea/jarRepositories.xml b/011.NScrolling_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/.idea/misc.xml b/011.NScrolling_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1373389627.json b/011.NScrolling_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1373389627.json
new file mode 100644
index 0000000000000000000000000000000000000000..f505e6b9ca3d41faf1f0a39a496db58b117fbd60
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1373389627.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1697959689.json b/011.NScrolling_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1697959689.json
new file mode 100644
index 0000000000000000000000000000000000000000..f505e6b9ca3d41faf1f0a39a496db58b117fbd60
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1697959689.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/.idea/previewer/previewConfig.json b/011.NScrolling_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..2039a10ef7f892db8eaacf34b193ba1786d4a4fc
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,12 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "E:\\ohosgitbub\\Test_Main\\MyApplication\\entry": [
+ "phone"
+ ],
+ "E:\\ohosgitbub\\Test_Main\\MyApplication\\recyclviewlibrary": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git "a/011.NScrolling_OpenHarmony-master/011.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204NScrolling\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/011.NScrolling_OpenHarmony-master/011.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204NScrolling\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..cdd5cb5e8d5ae5a94e7d31713179bfefd81df93b
Binary files /dev/null and "b/011.NScrolling_OpenHarmony-master/011.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204NScrolling\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/011.NScrolling_OpenHarmony-master/build.gradle b/011.NScrolling_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0f37d1b371f1632aaf2af4a2814463596cc0ddf0
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.2.5'
+ classpath 'com.huawei.ohos:decctest:1.0.0.6'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/011.NScrolling_OpenHarmony-master/entry/.gitignore b/011.NScrolling_OpenHarmony-master/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/011.NScrolling_OpenHarmony-master/entry/build.gradle b/011.NScrolling_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..da695fc21b692170f398b67123418efa90b3b647
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,24 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ signingConfigs {
+// debug {
+// storeFile file('E:/svnstudy/keystore/keystore.p12')
+// storePassword '0000001C7111B5C80725410DDFBFF2521CDA79E347E5DCB923A9F33885E548FCCAAE65DD247115E56480E43F'
+// keyAlias 'keystore'
+// keyPassword '0000001CC9E2B6E097687CD0A3D0A019C97D5FCC234B1FDDEB18FF3B86C6B22A67D096B0F9A2FAA154EAD6D2'
+// signAlg 'SHA256withECDSA'
+// profile file('E:/svnstudy/keystore/ohosDebug.p7b')
+// certpath file('E:/svnstudy/keystore/keystore.cer')
+// }
+ }
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ implementation project(path: ':recyclviewlibrary')
+ testCompile 'junit:junit:4.12'
+}
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/config.json b/011.NScrolling_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..75bb008fd925d84407b0b28ed07f649ca3ac645d
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,48 @@
+{
+ "app": {
+ "bundleName": "com.istone.harmony",
+ "vendor": "istone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.istone.myapplication",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.istone.myapplication.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "MyApplication",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/MainAbility.java b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f5df9d4d3e945b3ccd23df35605d49f69061bca
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/MainAbility.java
@@ -0,0 +1,13 @@
+package com.istone.myapplication;
+
+import com.istone.myapplication.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/MyApplication.java b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..f330e558b4722540a9acf6444b42c0f7171ee78e
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/MyApplication.java
@@ -0,0 +1,10 @@
+package com.istone.myapplication;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/adapter/RtProvider.java b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/adapter/RtProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..b96036b765a374c2f8b8b6c1dc06dd183a9830d0
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/adapter/RtProvider.java
@@ -0,0 +1,88 @@
+package com.istone.myapplication.adapter;
+
+import com.istone.myapplication.ResourceTable;
+import com.istone.recyclviewlibrary.moveview.NScrolling;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.agp.components.*;
+
+import java.util.List;
+
+/**
+ * @author: lehuangd
+ * @since : 2021/3/5
+ */
+public class RtProvider extends RecycleItemProvider {
+ private List data;
+ private AbilitySlice context;
+ private OnItemListener onItemListener;
+
+ public RtProvider(AbilitySlice abilitySlice, List list) {
+ context = abilitySlice;
+ data = list;
+ }
+
+ @Override
+ public int getCount() {
+ return data.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return data.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
+ Component cot = null;
+ if (component == null) {
+ cot = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item, null, false);
+ }else {
+ cot = component;
+ }
+ NScrolling nScrollview = (NScrolling) cot.findComponentById(ResourceTable.Id_scrollow);
+ DirectionalLayout directionalLayout = (DirectionalLayout) cot.findComponentById(ResourceTable.Id_layout);
+ DirectionalLayout directionalLayout1 = (DirectionalLayout) cot.findComponentById(ResourceTable.Id_reason);
+ DirectionalLayout directionalLayout2 = (DirectionalLayout) cot.findComponentById(ResourceTable.Id_direct);
+ Text text1 = (Text) cot.findComponentById(ResourceTable.Id_txt);
+ Text text = (Text) cot.findComponentById(ResourceTable.Id_delete);
+ text1.setText(data.get(i)+"");
+ text.setClickedListener(component1 -> {
+ onItemListener.itemClick(i);
+ });
+ nScrollview.setWidth(context, directionalLayout, directionalLayout1, directionalLayout2);
+ nScrollview.setTouchEventListener(nScrollview);
+
+ return cot;
+ }
+
+ /**
+ * 定义接口
+ */
+ public interface OnItemListener {
+ void itemClick(int position);
+ }
+
+ ;
+
+ /**
+ * 设置监听
+ *
+ * @param onItemListener l
+ */
+ public void setOnItemListener(OnItemListener onItemListener) {
+ this.onItemListener = onItemListener;
+ }
+
+ /**
+ * 移除数据
+ */
+ public void Remove(int i) {
+ data.remove(i);
+ notifyDataChanged();
+ }
+}
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/slice/MainAbilitySlice.java b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..4212d00389155f0700421f1bbe0d5371c912cc54
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/java/com/istone/myapplication/slice/MainAbilitySlice.java
@@ -0,0 +1,54 @@
+package com.istone.myapplication.slice;
+
+import com.istone.myapplication.ResourceTable;
+import com.istone.myapplication.adapter.RtProvider;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.ListContainer;
+
+import java.util.ArrayList;
+
+public class MainAbilitySlice extends AbilitySlice {
+ private ListContainer rtListContainer;
+ private RtProvider rtProvider;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ rtListContainer = (ListContainer) findComponentById(ResourceTable.Id_list);
+ rtProvider = new RtProvider(this, getData());
+ rtListContainer.setItemProvider(rtProvider);
+ rtProvider.setOnItemListener(new RtProvider.OnItemListener() {
+ @Override
+ public void itemClick(int position) {
+ rtProvider.Remove(position);
+ }
+ });
+
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+
+ /**
+ * 造数据
+ *
+ * @return list
+ */
+ private ArrayList getData() {
+ ArrayList list = new ArrayList<>();
+ for (int i = 0; i < 50; i++) {
+ list.add("测试" + i);
+ }
+ return list;
+ }
+}
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..6becfe43fc3852c05cb8654d79518be7487f6947
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "HelloWorld",
+ "value": "Hello World"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a002c2353e78af3a15235e00738328ff566bc085
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c7d007ad7145e0d638480b02f4bf0b60e07f898
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/layout/item.xml b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/layout/item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..26929fc6c2a1ab28cec3756e75d37b438c46ea39
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/layout/item.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/011.NScrolling_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/011.NScrolling_OpenHarmony-master/entry/src/test/java/com/istone/myapplication/ExampleTest.java b/011.NScrolling_OpenHarmony-master/entry/src/test/java/com/istone/myapplication/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8885355dbe7e22f3a6c70866a1563881c01ecd24
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/entry/src/test/java/com/istone/myapplication/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.istone.myapplication;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/011.NScrolling_OpenHarmony-master/gradle.properties b/011.NScrolling_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/011.NScrolling_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/011.NScrolling_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/011.NScrolling_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/011.NScrolling_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/011.NScrolling_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..f59159e865d4b59feb1b8c44b001f62fc5d58df4
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/011.NScrolling_OpenHarmony-master/gradlew b/011.NScrolling_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/011.NScrolling_OpenHarmony-master/gradlew.bat b/011.NScrolling_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/011.NScrolling_OpenHarmony-master/recyclviewlibrary/.gitignore b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/011.NScrolling_OpenHarmony-master/recyclviewlibrary/build.gradle b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..312bc1c336a2b750048a182991e5872344e45dbf
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile 'junit:junit:4.12'
+}
diff --git a/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/config.json b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..3a82cb7561399e38ffb3b5a3ca2c58d50c6db4a2
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.istone.myapplication",
+ "vendor": "istone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.istone.recyclviewlibrary",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "recyclviewlibrary",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/java/com/istone/recyclviewlibrary/moveview/NScrolling.java b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/java/com/istone/recyclviewlibrary/moveview/NScrolling.java
new file mode 100644
index 0000000000000000000000000000000000000000..7067417668d29c83f8cf92536c3d3b72e08ad52e
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/java/com/istone/recyclviewlibrary/moveview/NScrolling.java
@@ -0,0 +1,89 @@
+package com.istone.recyclviewlibrary.moveview;
+
+import com.istone.recyclviewlibrary.util.ScreenUtil;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.agp.components.*;
+import ohos.app.Context;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author: lehuangd
+ * @since : 2021/3/12
+ */
+public class NScrolling extends ScrollView implements Component.TouchEventListener {
+ private int pointX;
+ private int pointY;
+ private int EndpointX;
+ private int EndpointY;
+ private int moveWidth;
+ public static List nScrollingList = new LinkedList<>();
+
+ public NScrolling(Context context) {
+ super(context);
+ }
+
+ public NScrolling(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ }
+
+ public NScrolling(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ }
+
+ /**
+ * 设置滚动宽度
+ */
+ public void setWidth(AbilitySlice abilitySlice, DirectionalLayout directionalLayout,
+ DirectionalLayout directionalLayout1, DirectionalLayout directionalLayout2) {
+ directionalLayout.setWidth(ScreenUtil.getScreenWith(abilitySlice) + ScreenUtil.getCompactWith(directionalLayout2));
+ directionalLayout1.setWidth(ScreenUtil.getScreenWith(abilitySlice));
+ moveWidth = ScreenUtil.getCompactWith(directionalLayout2);
+ }
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+
+
+ switch (touchEvent.getAction()) {
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ pointX = (int) touchEvent.getPointerPosition(0).getX();
+ pointY = (int) touchEvent.getPointerPosition(0).getY();
+ if (nScrollingList.size() > 0) {
+ nScrollingList.get(0).fluentScrollXTo(0);
+ nScrollingList.removeAll(nScrollingList);
+ }
+ break;
+ case TouchEvent.PRIMARY_POINT_UP:
+ EndpointX = (int) touchEvent.getPointerPosition(0).getX();
+ EndpointY = (int) touchEvent.getPointerPosition(0).getY();
+ //有左向右滑动
+ if (pointX > EndpointX) {
+ if (pointX - EndpointX > 200) {
+ if (pointY - EndpointY < 50) {
+ NScrolling.this.fluentScrollXTo(moveWidth);
+ nScrollingList.add((NScrolling) component);
+ } else {
+ NScrolling.this.fluentScrollXTo(0);
+ }
+ } else {
+ NScrolling.this.fluentScrollXTo(0);
+ }
+ } else {
+ NScrolling.this.fluentScrollXTo(0);
+ }
+ break;
+ case TouchEvent.POINT_MOVE:
+ if ((pointX - EndpointX) > (pointY - EndpointY)) {
+ NScrolling.this.setEnabled(true);
+ } else {
+ NScrolling.this.setEnabled(false);
+ }
+ break;
+ }
+ return true;
+ }
+
+}
diff --git a/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/java/com/istone/recyclviewlibrary/util/ScreenUtil.java b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/java/com/istone/recyclviewlibrary/util/ScreenUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca92abc9bde5147b9343d954e7fe9654c6f54414
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/java/com/istone/recyclviewlibrary/util/ScreenUtil.java
@@ -0,0 +1,31 @@
+package com.istone.recyclviewlibrary.util;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.agp.components.Component;
+import ohos.agp.window.service.Display;
+import ohos.agp.window.service.DisplayAttributes;
+import ohos.agp.window.service.DisplayManager;
+
+import java.util.Optional;
+
+/**
+ * @author: lehuangd
+ * @since : 2021/3/15
+ */
+public class ScreenUtil {
+ /**
+ * 获取屏幕宽度
+ */
+ public static int getScreenWith(AbilitySlice abilitySlice){
+ // 获取屏幕密度
+ Optional display = DisplayManager.getInstance().getDefaultDisplay(abilitySlice.getContext());
+ DisplayAttributes displayAttributes = display.get().getAttributes();
+ return displayAttributes.width;
+ }
+ /**
+ * 获取组件宽度
+ */
+ public static int getCompactWith(Component component){
+ return component.getWidth();
+ }
+}
diff --git a/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/resources/base/element/string.json b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..c41f7823faab63e1beea0782c788f469331f5091
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/recyclviewlibrary/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "RecycleViewLibrary"
+ }
+ ]
+}
diff --git a/011.NScrolling_OpenHarmony-master/settings.gradle b/011.NScrolling_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..9d1f10e43da5637bd99660575c6a385e3c8cd6e7
--- /dev/null
+++ b/011.NScrolling_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':recyclviewlibrary'
diff --git a/012.RoundedImage_OpenHarmony-master/.gitignore b/012.RoundedImage_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/012.RoundedImage_OpenHarmony-master/.idea/.gitignore b/012.RoundedImage_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/012.RoundedImage_OpenHarmony-master/.idea/compiler.xml b/012.RoundedImage_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/.idea/gradle.xml b/012.RoundedImage_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ec6609ee80f4c08a9556d314d3607e1cbee2e939
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/.idea/jarRepositories.xml b/012.RoundedImage_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/.idea/misc.xml b/012.RoundedImage_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..58918f50335428f2efb3af4d621f9f405ed659d4
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git "a/012.RoundedImage_OpenHarmony-master/012\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204RoundedImage\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/012.RoundedImage_OpenHarmony-master/012\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204RoundedImage\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..f7304253fc1c550b5bca8d34eb5c6625fbf8372a
Binary files /dev/null and "b/012.RoundedImage_OpenHarmony-master/012\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204RoundedImage\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/012.RoundedImage_OpenHarmony-master/build.gradle b/012.RoundedImage_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0f37d1b371f1632aaf2af4a2814463596cc0ddf0
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.2.5'
+ classpath 'com.huawei.ohos:decctest:1.0.0.6'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build.gradle b/012.RoundedImage_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..f34a993791daeab18ed82fae3089f7daf7eac777
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ compile project(path: ':library')
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/buildConfig/debug/com/example/app/BuildConfig.java b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/buildConfig/debug/com/example/app/BuildConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..89cd2c8c670e0046a1be45de770504b68d933bdf
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/buildConfig/debug/com/example/app/BuildConfig.java
@@ -0,0 +1,11 @@
+/**
+ * Automatically generated file. DO NOT MODIFY
+ */
+package com.example.app;
+
+public final class BuildConfig {
+ public static final boolean DEBUG = Boolean.parseBoolean("true");
+ public static final String PACKAGE_NAME = "com.example.app";
+ public static final String BUILD_TYPE = "debug";
+ public static final int COMPILE_SDK_VERSION = 5;
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/R.jar b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/R.jar
new file mode 100644
index 0000000000000000000000000000000000000000..aa303bbca3a8efc0bb4bbeecda2dff98183c7f4e
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/R.jar differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/classes/com/custom/library/ResourceTable.class b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/classes/com/custom/library/ResourceTable.class
new file mode 100644
index 0000000000000000000000000000000000000000..fea0bb2f1bca4228f32b22d7ff56e4dd5caa76f4
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/classes/com/custom/library/ResourceTable.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/classes/com/example/app/ResourceTable.class b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/classes/com/example/app/ResourceTable.class
new file mode 100644
index 0000000000000000000000000000000000000000..eded57a08dd7db122dabd4674697239fae0b080a
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/classes/com/example/app/ResourceTable.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/com/custom/library/ResourceTable.java b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/com/custom/library/ResourceTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..edba3f3d26e408ebec68564e2a716e6e45ef67b2
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/com/custom/library/ResourceTable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright(c) Huawei Technologies Co., Ltd. 2019 - 2020. All rights reserved.
+ * Description: This header was automatically generated by restool from the resource data it found.
+ * It provides resource index information for applications, and should not be modified by hand.
+ */
+
+package com.custom.library;
+
+public final class ResourceTable {
+ public static final int Graphic_background_ability_main = 0x1000009;
+ public static final int Graphic_background_button = 0x100000a;
+ public static final int Graphic_background_photo = 0x100000b;
+
+ public static final int Id_button = 0x100000f;
+ public static final int Id_image1 = 0x1000010;
+ public static final int Id_image2 = 0x1000011;
+ public static final int Id_image3 = 0x1000012;
+ public static final int Id_second_button = 0x1000013;
+ public static final int Id_second_image1 = 0x1000014;
+ public static final int Id_second_image2 = 0x1000015;
+ public static final int Id_second_image3 = 0x1000016;
+ public static final int Id_second_text = 0x1000017;
+ public static final int Id_text = 0x1000018;
+ public static final int Id_third_button = 0x1000019;
+ public static final int Id_third_image1 = 0x100001a;
+ public static final int Id_third_image2 = 0x100001b;
+ public static final int Id_third_image3 = 0x100001c;
+ public static final int Id_third_text = 0x100001d;
+
+ public static final int Layout_ability_main = 0x100000c;
+ public static final int Layout_ability_second = 0x100000d;
+ public static final int Layout_ability_third = 0x100000e;
+
+ public static final int Media_icon = 0x1000002;
+ public static final int Media_photo = 0x1000003;
+ public static final int Media_photo1 = 0x1000004;
+ public static final int Media_photo2 = 0x1000005;
+ public static final int Media_photo3 = 0x1000006;
+ public static final int Media_photo4 = 0x1000007;
+ public static final int Media_photo5 = 0x1000008;
+
+ public static final int String_app_name = 0x1000000;
+ public static final int String_mainability_description = 0x1000001;
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/com/example/app/ResourceTable.java b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/com/example/app/ResourceTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..a14c1113d0bf6bc5dc43098948b787fa4470ac26
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/generated/source/r/com/example/app/ResourceTable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright(c) Huawei Technologies Co., Ltd. 2019 - 2020. All rights reserved.
+ * Description: This header was automatically generated by restool from the resource data it found.
+ * It provides resource index information for applications, and should not be modified by hand.
+ */
+
+package com.example.app;
+
+public final class ResourceTable {
+ public static final int Graphic_background_ability_main = 0x1000009;
+ public static final int Graphic_background_button = 0x100000a;
+ public static final int Graphic_background_photo = 0x100000b;
+
+ public static final int Id_button = 0x100000f;
+ public static final int Id_image1 = 0x1000010;
+ public static final int Id_image2 = 0x1000011;
+ public static final int Id_image3 = 0x1000012;
+ public static final int Id_second_button = 0x1000013;
+ public static final int Id_second_image1 = 0x1000014;
+ public static final int Id_second_image2 = 0x1000015;
+ public static final int Id_second_image3 = 0x1000016;
+ public static final int Id_second_text = 0x1000017;
+ public static final int Id_text = 0x1000018;
+ public static final int Id_third_button = 0x1000019;
+ public static final int Id_third_image1 = 0x100001a;
+ public static final int Id_third_image2 = 0x100001b;
+ public static final int Id_third_image3 = 0x100001c;
+ public static final int Id_third_text = 0x100001d;
+
+ public static final int Layout_ability_main = 0x100000c;
+ public static final int Layout_ability_second = 0x100000d;
+ public static final int Layout_ability_third = 0x100000e;
+
+ public static final int Media_icon = 0x1000002;
+ public static final int Media_photo = 0x1000003;
+ public static final int Media_photo1 = 0x1000004;
+ public static final int Media_photo2 = 0x1000005;
+ public static final int Media_photo3 = 0x1000006;
+ public static final int Media_photo4 = 0x1000007;
+ public static final int Media_photo5 = 0x1000008;
+
+ public static final int String_app_name = 0x1000000;
+ public static final int String_mainability_description = 0x1000001;
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/dex/debug/classes.dex b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/dex/debug/classes.dex
new file mode 100644
index 0000000000000000000000000000000000000000..7c5290615f9b23340eb8daa89ac9f2c9e2a5465e
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/dex/debug/classes.dex differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/META-INF/MANIFEST.MF b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..59499bce4a2bd51cba227b7c00fcf745b19c95a4
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/BuildConfig.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/BuildConfig.class
new file mode 100644
index 0000000000000000000000000000000000000000..3fd4459f93b0b0e4f85673bbf20c01fcc299125b
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/BuildConfig.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/ResourceTable.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/ResourceTable.class
new file mode 100644
index 0000000000000000000000000000000000000000..fea0bb2f1bca4228f32b22d7ff56e4dd5caa76f4
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/ResourceTable.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$1.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..fb6b2482a036d4dab2736f2d048599793e85fb37
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$1.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$2.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$2.class
new file mode 100644
index 0000000000000000000000000000000000000000..7d657ec31b70fee02c0e3457ec82ee3ceabf0020
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$2.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage.class
new file mode 100644
index 0000000000000000000000000000000000000000..34e1f1e19b6b9e099a40e3427f0bb7c86702c1f6
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/BuildConfig.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/BuildConfig.class
new file mode 100644
index 0000000000000000000000000000000000000000..31b2ac1cc2ad11beca33540c3c5c1407e7fddbc4
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/BuildConfig.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/MainAbility.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/MainAbility.class
new file mode 100644
index 0000000000000000000000000000000000000000..0e6596591886b70eacff95d5b5ad18ff5fc4d767
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/MainAbility.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/MyApplication.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/MyApplication.class
new file mode 100644
index 0000000000000000000000000000000000000000..b7cd2e7ba259410ef12242f340b98a066945b84e
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/MyApplication.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/ResourceTable.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/ResourceTable.class
new file mode 100644
index 0000000000000000000000000000000000000000..eded57a08dd7db122dabd4674697239fae0b080a
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/ResourceTable.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/MainAbilitySlice$1.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/MainAbilitySlice$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..85fef7c154feaeb4800598d6269eb80589e90341
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/MainAbilitySlice$1.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/MainAbilitySlice.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/MainAbilitySlice.class
new file mode 100644
index 0000000000000000000000000000000000000000..7beb5c81373851c05b192dab7c0333578b3878d1
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/MainAbilitySlice.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/SecondSlice$1.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/SecondSlice$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..540169c5de0c0b9f748db838c32e7dea3fb4e3f5
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/SecondSlice$1.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/SecondSlice.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/SecondSlice.class
new file mode 100644
index 0000000000000000000000000000000000000000..b31ffbef731d38ca7eee4aa81133f971095cd5a4
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/SecondSlice.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/ThirdSlice$1.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/ThirdSlice$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..872d309a6563d791607bad28f16ac40791fa34de
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/ThirdSlice$1.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/ThirdSlice.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/ThirdSlice.class
new file mode 100644
index 0000000000000000000000000000000000000000..730d0fef35641b7b19d187f4d09057e1fa51c2bb
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/javac/debug/classes/com/example/app/slice/ThirdSlice.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_profile/debug/config.json b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_profile/debug/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..48210df944cf7737882a6294b25eb4bbebbb0826
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_profile/debug/config.json
@@ -0,0 +1,52 @@
+{
+ "app": {
+ "bundleName": "com.example.app",
+ "vendor": "example",
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ },
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ }
+ },
+ "deviceConfig": {
+
+ },
+ "module": {
+ "name": ".MyApplication",
+ "deviceType": [
+ "tv",
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry",
+ "installationFree": true
+ },
+ "abilities": [
+ {
+ "name": "com.example.app.MainAbility",
+ "description": "$string:mainability_description",
+ "icon": "$media:icon",
+ "label": "App",
+ "type": "page",
+ "launchType": "standard",
+ "orientation": "unspecified",
+ "skills": [
+ {
+ "actions": [
+ "action.system.home"
+ ],
+ "entities": [
+ "entity.system.home"
+ ]
+ }
+ ]
+ }
+ ],
+ "package": "com.example.app"
+ }
+}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/merge_res_file.index b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/merge_res_file.index
new file mode 100644
index 0000000000000000000000000000000000000000..67e7960a2100374bbf5cf32904de906a592939ec
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/merge_res_file.index
@@ -0,0 +1,2 @@
+"C:\Users\issuser\AppData\Roaming\WeLink\appdata\IM\leiwang_825@isoftstone\ReceiveFiles\haros\RoundedImage_HarmonyOS-master\entry\src\main"
+"C:\Users\issuser\AppData\Roaming\WeLink\appdata\IM\leiwang_825@isoftstone\ReceiveFiles\haros\RoundedImage_HarmonyOS-master\library\build\.transforms\1fe698bd4738d220ef9c8ace5b7ca52b\library-debug"
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/original_res/res/drawable/icon.png b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/original_res/res/drawable/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/original_res/res/drawable/icon.png differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/original_res/res/values/strings.xml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/original_res/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b05c432ceb331537c0997baf140d40b601f2ab44
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/merge_res/debug/original_res/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ "Java_Phone_Empty Feature Ability"
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/R.txt b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/R.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ced1cced3a301c0886f6ee833b3c95bcacee8c45
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/R.txt
@@ -0,0 +1,30 @@
+graphic background_ability_main 0x1000009
+graphic background_button 0x100000a
+graphic background_photo 0x100000b
+id button 0x100000f
+id image1 0x1000010
+id image2 0x1000011
+id image3 0x1000012
+id second_button 0x1000013
+id second_image1 0x1000014
+id second_image2 0x1000015
+id second_image3 0x1000016
+id second_text 0x1000017
+id text 0x1000018
+id third_button 0x1000019
+id third_image1 0x100001a
+id third_image2 0x100001b
+id third_image3 0x100001c
+id third_text 0x100001d
+layout ability_main 0x100000c
+layout ability_second 0x100000d
+layout ability_third 0x100000e
+media icon 0x1000002
+media photo 0x1000003
+media photo1 0x1000004
+media photo2 0x1000005
+media photo3 0x1000006
+media photo4 0x1000007
+media photo5 0x1000008
+string app_name 0x1000000
+string mainability_description 0x1000001
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/config.json b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..e836d92cf5373acd0eadc5878c9f967ff3706957
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/config.json
@@ -0,0 +1,54 @@
+{
+ "app": {
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ },
+ "vendor": "example",
+ "bundleName": "com.example.app",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ }
+ },
+ "deviceConfig": {
+
+ },
+ "module": {
+ "abilities": [
+ {
+ "iconId": 16777218,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "descriptionId": 16777217,
+ "icon": "$media:icon",
+ "name": "com.example.app.MainAbility",
+ "description": "$string:mainability_description",
+ "label": "App",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "deviceType": [
+ "tv",
+ "phone"
+ ],
+ "distro": {
+ "moduleType": "entry",
+ "installationFree": true,
+ "deliveryWithInstall": true,
+ "moduleName": "entry"
+ },
+ "package": "com.example.app",
+ "name": ".MyApplication"
+ }
+}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources.index b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources.index
new file mode 100644
index 0000000000000000000000000000000000000000..4ea3b1e4a2201dfc48251935137101ccd622e058
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources.index differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/attributes.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/attributes.key
new file mode 100644
index 0000000000000000000000000000000000000000..93295c6b610eadaf621e80422e2915de91b3b21c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/attributes.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_ability_main.sxml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_ability_main.sxml
new file mode 100644
index 0000000000000000000000000000000000000000..b7f48aa765f62acd0086316932f0bc8a995dc5d7
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_ability_main.sxml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_button.sxml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_button.sxml
new file mode 100644
index 0000000000000000000000000000000000000000..d785706c1058c76c818e2ff619bd5bd97f5177e6
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_button.sxml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_photo.sxml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_photo.sxml
new file mode 100644
index 0000000000000000000000000000000000000000..3d7107c55b08a8aee533b56f5e4a21015903840d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/background_photo.sxml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/constants.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/constants.key
new file mode 100644
index 0000000000000000000000000000000000000000..88b275059943e535b5068591515769a7844442ba
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/constants.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/contents.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/contents.key
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/contents.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/nodes.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/nodes.key
new file mode 100644
index 0000000000000000000000000000000000000000..d89c218656381e325e6d2c59d2faba328a2d8107
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/graphic/nodes.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_main.sxml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_main.sxml
new file mode 100644
index 0000000000000000000000000000000000000000..f5fa1bb578c7a8ed0cd95b54d4354781e6349ae7
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_main.sxml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_second.sxml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_second.sxml
new file mode 100644
index 0000000000000000000000000000000000000000..9fe9790b9a68aea73a8cd7996f84b789e3bd05dc
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_second.sxml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_third.sxml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_third.sxml
new file mode 100644
index 0000000000000000000000000000000000000000..5f271729c5026b62d000ac5fca085d2b3c2e785a
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/ability_third.sxml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/attributes.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/attributes.key
new file mode 100644
index 0000000000000000000000000000000000000000..a3bbed59b21858077a43ddc13c2f2a713f66cb76
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/attributes.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/constants.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/constants.key
new file mode 100644
index 0000000000000000000000000000000000000000..e784ded624650800c07f8771105d58a544e87cc2
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/constants.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/contents.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/contents.key
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/contents.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/nodes.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/nodes.key
new file mode 100644
index 0000000000000000000000000000000000000000..c2987ae5a5a19cc4f83479ad0183d8b6dc14f27b
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/layout/nodes.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/attributes.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/attributes.key
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/attributes.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/constants.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/constants.key
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/constants.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/contents.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/contents.key
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/contents.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/icon.png b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..8966a1e3de00956d251d5c1497aa251ea7b5c49f
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/icon.png differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/nodes.key b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/nodes.key
new file mode 100644
index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/nodes.key differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo.jpg b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3c4d15019818640cd309b38ec22e30bf02060cee
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo1.jpg b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..486999dba5bfb0e731785cecff16b9e042e3c6bb
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo1.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo2.PNG b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo2.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..f0502d3b440a1c92a49069ea4400706ee974d640
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo2.PNG differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo3.jpg b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo3.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3203f5e9e90506ff5b13c3f4bd60ff1f1184adbe
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo3.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo4.jpg b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo4.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..62f5dd7d41a8961b4bca9a2c7bdd66f771e54dd6
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo4.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo5.jpg b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo5.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5b2bd91e8997b3fbfaee05404572ab88a3d6ee90
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/res/debug/rich/resources/base/media/photo5.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/dex/classes.dex b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/dex/classes.dex
new file mode 100644
index 0000000000000000000000000000000000000000..95a5fbb8910fbcc15f2e8aa226f972ab0256144c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/dex/classes.dex differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes.jar b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes.jar
new file mode 100644
index 0000000000000000000000000000000000000000..3c354a6684eec36257e46e8469b6bca511c2ad7a
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes.jar differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/MainAbilityShellActivity.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/MainAbilityShellActivity.class
new file mode 100644
index 0000000000000000000000000000000000000000..2841b38b1700691728d550a4728a303d0ac4e769
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/MainAbilityShellActivity.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R$drawable.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R$drawable.class
new file mode 100644
index 0000000000000000000000000000000000000000..36e420c06976c1ed582c8164a6ba501e2cf32ef5
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R$drawable.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R$string.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R$string.class
new file mode 100644
index 0000000000000000000000000000000000000000..af013b5f08b567c461fd3f02bd3773366fb08a22
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R$string.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R.class
new file mode 100644
index 0000000000000000000000000000000000000000..34e30f8ec9af98daaacc9585da20ab0a75f74e08
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/R.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/ShellMyApplication.class b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/ShellMyApplication.class
new file mode 100644
index 0000000000000000000000000000000000000000..ad2d1e1fcebe4c98e7625901e41cc3bf2d39264c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/javac/classes/com/example/app/ShellMyApplication.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/mergedManifest/AndroidManifest.xml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/mergedManifest/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..602606c9a0211569010149e9038e65ffe7d56af2
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/mergedManifest/AndroidManifest.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry.zip b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry.zip
new file mode 100644
index 0000000000000000000000000000000000000000..33d9cd9bc05534ccf9bce2a63f670227e543a4db
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry.zip differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/AndroidManifest.xml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f5bedd69873e0a0eabc1d0551af77e0201c764ee
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/AndroidManifest.xml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/classes.dex b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/classes.dex
new file mode 100644
index 0000000000000000000000000000000000000000..95a5fbb8910fbcc15f2e8aa226f972ab0256144c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/classes.dex differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/res/drawable/icon.png b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/res/drawable/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d912df1fc7eb485da25b48d0c8d7e59652484b90
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/res/drawable/icon.png differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/resources.arsc b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/resources.arsc
new file mode 100644
index 0000000000000000000000000000000000000000..95c6696a1e8134df83c88e606219f0a88c40c147
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/cut_entry/resources.arsc differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry.zip b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry.zip
new file mode 100644
index 0000000000000000000000000000000000000000..7bcd8b844fcd0344071c5d7ab6d1179651fc1770
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry.zip differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/AndroidManifest.xml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2ed1da53f4203fa960d6e04026415df5c57e1b6d
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/AndroidManifest.xml differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/classes.dex b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/classes.dex
new file mode 100644
index 0000000000000000000000000000000000000000..95a5fbb8910fbcc15f2e8aa226f972ab0256144c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/classes.dex differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/res/drawable/icon.png b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/res/drawable/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d912df1fc7eb485da25b48d0c8d7e59652484b90
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/res/drawable/icon.png differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/resources.arsc b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/resources.arsc
new file mode 100644
index 0000000000000000000000000000000000000000..95c6696a1e8134df83c88e606219f0a88c40c147
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/entry/resources.arsc differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/r/com/example/app/R.java b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/r/com/example/app/R.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b221f20bb7cee374278758297dbbbf6a4a0c49a
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/r/com/example/app/R.java
@@ -0,0 +1,17 @@
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+
+package com.example.app;
+
+public final class R {
+ public static final class drawable {
+ public static final int icon=0x7f010000;
+ }
+ public static final class string {
+ public static final int mainability_description=0x7f020000;
+ }
+}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/res.zip b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/res.zip
new file mode 100644
index 0000000000000000000000000000000000000000..c894ea56c9d123d01939e24b4e6f7792313028fe
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/res/res.zip differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/simplifyManifest/AndroidManifest.xml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/simplifyManifest/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..040d56f1ffa6c11d02c86c98d0a71d014e013534
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/build/simplifyManifest/AndroidManifest.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/AndroidManifest.xml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..59280c364f8ef1f144bf7a40cb18752d9bb4ce04
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/AndroidManifest.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/java/com/example/app/MainAbilityShellActivity.java b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/java/com/example/app/MainAbilityShellActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5985308713b30406d655d8810aa2826fd8de5ea
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/java/com/example/app/MainAbilityShellActivity.java
@@ -0,0 +1,11 @@
+package com.example.app;
+
+import android.os.Bundle;
+import ohos.abilityshell.AbilityShellActivity;
+
+public class MainAbilityShellActivity extends AbilityShellActivity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/java/com/example/app/ShellMyApplication.java b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/java/com/example/app/ShellMyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..1370c59b1429440fc368c28a49b80d60963a70e3
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/java/com/example/app/ShellMyApplication.java
@@ -0,0 +1,10 @@
+package com.example.app;
+
+import ohos.abilityshell.HarmonyApplication;
+
+public class ShellMyApplication extends HarmonyApplication {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/res/drawable/icon.png b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/res/drawable/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/res/drawable/icon.png differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/res/values/strings.xml b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..710d0dff33f3086066c7431e69a9a36ea72a4a7a
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell/debug/src/main/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+
+
+ "Java_Phone_Empty Feature Ability"
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/cut/entry_debug_unsigned_cut_entry.apk b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/cut/entry_debug_unsigned_cut_entry.apk
new file mode 100644
index 0000000000000000000000000000000000000000..dcb36303fca0c8f43f0536ec9213703f58765a32
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/cut/entry_debug_unsigned_cut_entry.apk differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/entry_debug_signed_entry.apk b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/entry_debug_signed_entry.apk
new file mode 100644
index 0000000000000000000000000000000000000000..1e86a3f59bfb1fdbfa50b5ad1fac006416185680
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/entry_debug_signed_entry.apk differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/entry_debug_unsigned_entry.apk b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/entry_debug_unsigned_entry.apk
new file mode 100644
index 0000000000000000000000000000000000000000..83e494f5c08232ecf7faa4a55163cfe24245b090
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/intermediates/shell_output/debug/entry_debug_unsigned_entry.apk differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/outputs/hap/debug/entry-debug-rich-unsigned.hap b/012.RoundedImage_OpenHarmony-master/entry/build/outputs/hap/debug/entry-debug-rich-unsigned.hap
new file mode 100644
index 0000000000000000000000000000000000000000..4ab37b51a408eb4845da36125fd87d9f08a243fd
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/build/outputs/hap/debug/entry-debug-rich-unsigned.hap differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/outputs/hap/debug/hapInfo.json b/012.RoundedImage_OpenHarmony-master/entry/build/outputs/hap/debug/hapInfo.json
new file mode 100644
index 0000000000000000000000000000000000000000..1ceec14611db660fcfffa7ab1f7ac48fc0b470af
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/outputs/hap/debug/hapInfo.json
@@ -0,0 +1,10 @@
+[
+ {
+ "hapPath": "entry-debug-rich-unsigned.hap",
+ "device": "phone"
+ },
+ {
+ "hapPath": "entry-debug-rich-unsigned.hap",
+ "device": "tv"
+ }
+]
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/tmp/packageDebugRClass/MANIFEST.MF b/012.RoundedImage_OpenHarmony-master/entry/build/tmp/packageDebugRClass/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..59499bce4a2bd51cba227b7c00fcf745b19c95a4
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/tmp/packageDebugRClass/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/build/tmp/packageDebugShellClass/MANIFEST.MF b/012.RoundedImage_OpenHarmony-master/entry/build/tmp/packageDebugShellClass/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..59499bce4a2bd51cba227b7c00fcf745b19c95a4
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/build/tmp/packageDebugShellClass/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/config.json b/012.RoundedImage_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..534257e503e902f521645b205351c28b36cd4200
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.example.app",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.app",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone",
+ "tv"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.app.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "App",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/MainAbility.java b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..388fa484ccd655db29568d0216c21ab66b5442dc
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.app;
+
+import com.example.app.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/MyApplication.java b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..72495b99b09b536bd5510419c2a15cea5d608b83
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.app;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/MainAbilitySlice.java b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..33c2a48eb99bee9898caf031a3a6040be2b16217
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/MainAbilitySlice.java
@@ -0,0 +1,56 @@
+package com.example.app.slice;
+
+import com.custom.library.RoundedImage;
+import com.example.app.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.agp.utils.Color;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class MainAbilitySlice extends AbilitySlice {
+ private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MainSlice");
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ RoundedImage roundedImage1 = (RoundedImage) findComponentById(ResourceTable.Id_image1);
+ roundedImage1.setPixelMapToRoundedRect(ResourceTable.Media_photo, 100, 50, 100, 50);
+
+ RoundedImage roundedImage2 = (RoundedImage) findComponentById(ResourceTable.Id_image2);
+ roundedImage2.setPixelMapToRoundedRect(ResourceTable.Media_photo1, 100, 100, 100, 100);
+
+ RoundedImage roundedImage3 = (RoundedImage) findComponentById(ResourceTable.Id_image3);
+ roundedImage3.setPixelMapToRoundedRect(ResourceTable.Media_photo2, 50, 100, 50, 100);
+
+ Text text = (Text) findComponentById(ResourceTable.Id_text);
+ text.setText("rounded");
+ text.setTextColor(Color.BLACK);
+ text.setTextSize(100);
+
+ Button button = (Button) findComponentById(ResourceTable.Id_button);
+ button.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ SecondSlice secondSlice = new SecondSlice();
+ Intent intent1 = new Intent();
+ present(secondSlice, intent1);
+ }
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/SecondSlice.java b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/SecondSlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7446338e14817a9f3c22b9f83ca07af3eb6b66b
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/SecondSlice.java
@@ -0,0 +1,46 @@
+package com.example.app.slice;
+
+import com.custom.library.RoundedImage;
+import com.example.app.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.agp.utils.Color;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class SecondSlice extends AbilitySlice {
+ private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00202, "SecondSlice");
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_second);
+
+ RoundedImage roundedImage1 = (RoundedImage) findComponentById(ResourceTable.Id_second_image1);
+ roundedImage1.setPixelMapToCircleImage(ResourceTable.Media_photo);
+
+ RoundedImage roundedImage2 = (RoundedImage) findComponentById(ResourceTable.Id_second_image2);
+ roundedImage2.setPixelMapToCircleImage(ResourceTable.Media_photo1);
+
+ RoundedImage roundedImage3 = (RoundedImage) findComponentById(ResourceTable.Id_second_image3);
+ roundedImage3.setPixelMapToCircleImage(ResourceTable.Media_photo2);
+
+ Text text = (Text) findComponentById(ResourceTable.Id_second_text);
+ text.setText("circle");
+ text.setTextColor(Color.BLACK);
+ text.setTextSize(100);
+
+ Button button = (Button) findComponentById(ResourceTable.Id_second_button);
+ button.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ ThirdSlice thirdSlice = new ThirdSlice();
+ Intent intent1 = new Intent();
+ present(thirdSlice, intent1);
+ }
+ });
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/ThirdSlice.java b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/ThirdSlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..33988e9e8eb022a82ed1531b001d9d5565879519
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/java/com/example/app/slice/ThirdSlice.java
@@ -0,0 +1,46 @@
+package com.example.app.slice;
+
+import com.custom.library.RoundedImage;
+import com.example.app.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.agp.utils.Color;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class ThirdSlice extends AbilitySlice {
+ private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00203, "ThirdSlice");
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_third);
+
+ RoundedImage roundedImage1 = (RoundedImage) findComponentById(ResourceTable.Id_third_image1);
+ roundedImage1.setPixelMapToOvalImage(ResourceTable.Media_photo3);
+
+ RoundedImage roundedImage2 = (RoundedImage) findComponentById(ResourceTable.Id_third_image2);
+ roundedImage2.setPixelMapToOvalImage(ResourceTable.Media_photo4);
+
+ RoundedImage roundedImage3 = (RoundedImage) findComponentById(ResourceTable.Id_third_image3);
+ roundedImage3.setPixelMapToOvalImage(ResourceTable.Media_photo5);
+
+ Text text = (Text) findComponentById(ResourceTable.Id_third_text);
+ text.setText("oval");
+ text.setTextColor(Color.BLACK);
+ text.setTextSize(100);
+
+ Button button = (Button) findComponentById(ResourceTable.Id_third_button);
+ button.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ MainAbilitySlice mainAbilitySlice = new MainAbilitySlice();
+ Intent intent1 = new Intent();
+ present(mainAbilitySlice, intent1);
+ }
+ });
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..60bf6758c1587350fc47480a4f6ae92b562ebe1b
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "App"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button.xml b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..668c5c813c4e3cfe99445bcf4bddf1ec5e218235
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_photo.xml b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_photo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e8ad58d869fb9bafc3c83a250f5bb9ed08b91f48
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_photo.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a8dbb1193e29b18dd6d1737f9a05c3e09f41d9ad
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_second.xml b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_second.xml
new file mode 100644
index 0000000000000000000000000000000000000000..18ffa6ec99ccd7e8ce7f25df2624acf389d380a6
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_second.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_third.xml b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_third.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ead0e1bafd6abcd9907351288944a875e887a9f9
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_third.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo.jpg b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3c4d15019818640cd309b38ec22e30bf02060cee
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo1.jpg b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..486999dba5bfb0e731785cecff16b9e042e3c6bb
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo1.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo2.PNG b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo2.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..f0502d3b440a1c92a49069ea4400706ee974d640
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo2.PNG differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo3.jpg b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo3.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3203f5e9e90506ff5b13c3f4bd60ff1f1184adbe
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo3.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo4.jpg b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo4.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..62f5dd7d41a8961b4bca9a2c7bdd66f771e54dd6
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo4.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo5.jpg b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo5.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5b2bd91e8997b3fbfaee05404572ab88a3d6ee90
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/entry/src/main/resources/base/media/photo5.jpg differ
diff --git a/012.RoundedImage_OpenHarmony-master/entry/src/test/java/com/example/app/ExampleTest.java b/012.RoundedImage_OpenHarmony-master/entry/src/test/java/com/example/app/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..56644cd0764679dab39aa701d3a9b2bad4f7166f
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/entry/src/test/java/com/example/app/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.app;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/gradle.properties b/012.RoundedImage_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/012.RoundedImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/012.RoundedImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/012.RoundedImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/012.RoundedImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/012.RoundedImage_OpenHarmony-master/gradlew b/012.RoundedImage_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/012.RoundedImage_OpenHarmony-master/gradlew.bat b/012.RoundedImage_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/012.RoundedImage_OpenHarmony-master/library/build.gradle b/012.RoundedImage_OpenHarmony-master/library/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b.bin b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b.bin
new file mode 100644
index 0000000000000000000000000000000000000000..3a91794a16a4cf824ec4fc6044c8df119efa2cf9
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b.bin
@@ -0,0 +1 @@
+o/library-debug
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/ResourceTable.txt b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/ResourceTable.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0a069bdfb330eacc1324f373ad200b3cdef9b3d6
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/ResourceTable.txt
@@ -0,0 +1 @@
+string app_name 0x2000000
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/classes.jar b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/classes.jar
new file mode 100644
index 0000000000000000000000000000000000000000..14f529c66e4cf191b5f499c2a8e3a68a215d3da5
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/classes.jar differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/config.json b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..0362c9452a39793ee3192e876a9b9e66de547538
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/config.json
@@ -0,0 +1 @@
+{"app": {"bundleName": "com.example.app","vendor": "custom","version": {"code": 1,"name": "1.0"},"apiVersion": {"compatible": 5,"target": 5,"releaseType": "Beta1"}},"deviceConfig": {},"module": {"package": "com.custom.library","deviceType": ["phone"],"distro": {"deliveryWithInstall": true,"moduleName": "library","moduleType": "har"}}}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/resources/base/element/string.json b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..0a144826f9c5a27417474ce52237f80fa7f458c2
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/1fe698bd4738d220ef9c8ace5b7ca52b/library-debug/resources/base/element/string.json
@@ -0,0 +1 @@
+{"string": [{"name": "app_name","value": "library"}]}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/975ca2a1c8adf4405b3af0edf9eb0811.bin b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/975ca2a1c8adf4405b3af0edf9eb0811.bin
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/a54e396785671aa66dbefb56f1e3b85e.bin b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/a54e396785671aa66dbefb56f1e3b85e.bin
new file mode 100644
index 0000000000000000000000000000000000000000..2222d173a929be31d81c8817b07bcf6566a34280
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/a54e396785671aa66dbefb56f1e3b85e.bin
@@ -0,0 +1 @@
+o/library-release
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/.transforms/eb0f3589bb7939f4b7cfc19e0bb08042.bin b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/eb0f3589bb7939f4b7cfc19e0bb08042.bin
new file mode 100644
index 0000000000000000000000000000000000000000..820761fabac0cbfbc845e194f2894bb8311ddbfb
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/.transforms/eb0f3589bb7939f4b7cfc19e0bb08042.bin
@@ -0,0 +1 @@
+i/classes.jar
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/generated/source/buildConfig/debug/com/custom/library/BuildConfig.java b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/buildConfig/debug/com/custom/library/BuildConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..62e2959f2b81f2ffa557c36683b255888e64c1ed
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/buildConfig/debug/com/custom/library/BuildConfig.java
@@ -0,0 +1,11 @@
+/**
+ * Automatically generated file. DO NOT MODIFY
+ */
+package com.custom.library;
+
+public final class BuildConfig {
+ public static final boolean DEBUG = Boolean.parseBoolean("true");
+ public static final String PACKAGE_NAME = "com.custom.library";
+ public static final String BUILD_TYPE = "debug";
+ public static final int COMPILE_SDK_VERSION = 5;
+}
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/R.jar b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/R.jar
new file mode 100644
index 0000000000000000000000000000000000000000..85d39c6a5481b1629640e4f2217e49ea34d38b53
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/R.jar differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/classes/com/custom/library/ResourceTable.class b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/classes/com/custom/library/ResourceTable.class
new file mode 100644
index 0000000000000000000000000000000000000000..b1aff0d1f012126f7d2c76301ab79023ea9bba78
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/classes/com/custom/library/ResourceTable.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/com/custom/library/ResourceTable.java b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/com/custom/library/ResourceTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6d650c3c2405a3f0a5eb746e160c2d653847105
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/generated/source/r/com/custom/library/ResourceTable.java
@@ -0,0 +1,11 @@
+/*
+ * Copyright(c) Huawei Technologies Co., Ltd. 2019 - 2020. All rights reserved.
+ * Description: This header was automatically generated by restool from the resource data it found.
+ * It provides resource index information for applications, and should not be modified by hand.
+ */
+
+package com.custom.library;
+
+public final class ResourceTable {
+ public static int String_app_name = 0x2000000;
+}
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes.jar b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes.jar
new file mode 100644
index 0000000000000000000000000000000000000000..14f529c66e4cf191b5f499c2a8e3a68a215d3da5
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes.jar differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/BuildConfig.class b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/BuildConfig.class
new file mode 100644
index 0000000000000000000000000000000000000000..3fd4459f93b0b0e4f85673bbf20c01fcc299125b
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/BuildConfig.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$1.class b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..fb6b2482a036d4dab2736f2d048599793e85fb37
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$1.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$2.class b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$2.class
new file mode 100644
index 0000000000000000000000000000000000000000..7d657ec31b70fee02c0e3457ec82ee3ceabf0020
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage$2.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage.class b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage.class
new file mode 100644
index 0000000000000000000000000000000000000000..34e1f1e19b6b9e099a40e3427f0bb7c86702c1f6
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/javac/debug/classes/com/custom/library/RoundedImage.class differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/merge_res/debug/merge_res_file.index b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/merge_res/debug/merge_res_file.index
new file mode 100644
index 0000000000000000000000000000000000000000..81c8d86dfdf71c7402b7c72b714062ab3dff34b9
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/merge_res/debug/merge_res_file.index
@@ -0,0 +1 @@
+"C:\Users\issuser\AppData\Roaming\WeLink\appdata\IM\leiwang_825@isoftstone\ReceiveFiles\haros\RoundedImage_HarmonyOS-master\library\src\main"
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/R.txt b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/R.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0a069bdfb330eacc1324f373ad200b3cdef9b3d6
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/R.txt
@@ -0,0 +1 @@
+string app_name 0x2000000
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/ResourceTable.txt b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/ResourceTable.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0a069bdfb330eacc1324f373ad200b3cdef9b3d6
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/ResourceTable.txt
@@ -0,0 +1 @@
+string app_name 0x2000000
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/config.json b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..176969ae07d711ee2927b21b8228204b30dc1fca
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/config.json
@@ -0,0 +1,33 @@
+{
+ "app" :
+ {
+ "apiVersion" :
+ {
+ "compatible" : 5,
+ "releaseType" : "Beta1",
+ "target" : 5
+ },
+ "bundleName" : "com.example.app",
+ "vendor" : "custom",
+ "version" :
+ {
+ "code" : 1,
+ "name" : "1.0"
+ }
+ },
+ "deviceConfig" : {},
+ "module" :
+ {
+ "deviceType" :
+ [
+ "phone"
+ ],
+ "distro" :
+ {
+ "deliveryWithInstall" : true,
+ "moduleName" : "library",
+ "moduleType" : "har"
+ },
+ "package" : "com.custom.library"
+ }
+}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/resources.index b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/resources.index
new file mode 100644
index 0000000000000000000000000000000000000000..e32f7382d734d18eed57cdab2ccc3496a339e291
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/intermediates/res/debug/rich/resources.index differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/outputs/har/debug/library-debug.har b/012.RoundedImage_OpenHarmony-master/library/build/outputs/har/debug/library-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..ecc23b0194d268e78fe0f8c56e613beb7702064a
Binary files /dev/null and b/012.RoundedImage_OpenHarmony-master/library/build/outputs/har/debug/library-debug.har differ
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/tmp/generateDebugClassesJar/MANIFEST.MF b/012.RoundedImage_OpenHarmony-master/library/build/tmp/generateDebugClassesJar/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..59499bce4a2bd51cba227b7c00fcf745b19c95a4
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/tmp/generateDebugClassesJar/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/012.RoundedImage_OpenHarmony-master/library/build/tmp/packageDebugRClass/MANIFEST.MF b/012.RoundedImage_OpenHarmony-master/library/build/tmp/packageDebugRClass/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..59499bce4a2bd51cba227b7c00fcf745b19c95a4
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/build/tmp/packageDebugRClass/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/012.RoundedImage_OpenHarmony-master/library/src/main/config.json b/012.RoundedImage_OpenHarmony-master/library/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..6749788ce35b53b6cef487dc2169cd48e934f1ac
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.app",
+ "vendor": "custom",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.custom.library",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "library",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/012.RoundedImage_OpenHarmony-master/library/src/main/java/com/custom/library/RoundedImage.java b/012.RoundedImage_OpenHarmony-master/library/src/main/java/com/custom/library/RoundedImage.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef5683be2fc0815519f9b789e957506ef751d92c
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/src/main/java/com/custom/library/RoundedImage.java
@@ -0,0 +1,193 @@
+package com.custom.library;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.render.*;
+import ohos.agp.utils.RectFloat;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+import ohos.media.image.common.Rect;
+import ohos.media.image.common.Size;
+
+import java.io.FileDescriptor;
+import java.io.InputStream;
+
+public class RoundedImage extends Image {
+ private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00200, "Lib");
+
+ private PixelMapHolder holder = null;
+ private int minImageLength = 0;
+
+ /**
+ * 默认构造函数,用于使用默认属性集和样式创建图像实例。
+ *
+ * @param context 应用程序上下文
+ */
+ public RoundedImage(Context context) {
+ super(context);
+ }
+
+ /**
+ * 用于在解析XML文件后使用指定的属性集和默认样式创建图像实例的构造函数。
+ *
+ * @param context 应用程序上下文
+ * @param attrSet 要使用的属性集
+ */
+ public RoundedImage(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ }
+
+ /**
+ * 用于在解析XML文件后使用指定的属性集和指定的样式创建图像实例的构造函数。
+ *
+ * @param context 应用程序上下文
+ * @param attrSet 要使用的属性集
+ * @param styleName 要使用的样式名称
+ */
+ public RoundedImage(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ }
+
+ /**
+ * 设置图片显示成圆形
+ *
+ * @param resId 资源ID
+ */
+ public void setPixelMapToCircleImage(int resId) {
+ initVariable(getPixelMap(resId));
+ createCircleImage();
+ }
+
+ /**
+ * 设置图片显示成圆形
+ *
+ * @param fileDescriptor 图像源文件的描述符
+ */
+ public void setPixelMapToCircleImage(FileDescriptor fileDescriptor) {
+ initVariable(getPixelMap(fileDescriptor));
+ createCircleImage();
+ }
+
+ /**
+ * 设置椭圆图片
+ *
+ * @param resId 资源ID
+ */
+ public void setPixelMapToOvalImage(int resId) {
+ initVariable(getPixelMap(resId));
+ createOvalImage();
+ }
+
+ /**
+ * 设置椭圆图片
+ *
+ * @param fileDescriptor 图像源文件的描述符
+ */
+ public void setPixelMapToToOvalImage(FileDescriptor fileDescriptor) {
+ initVariable(getPixelMap(fileDescriptor));
+ createOvalImage();
+ }
+
+ /**
+ * 图片显示圆角
+ *
+ * @param resId 资源ID
+ * @param topLeft 左上圆角半径
+ * @param topRigth 右上圆角半径
+ * @param bottomRight 右下圆角半径
+ * @param bottomLeft 左下圆角半径
+ */
+ public void setPixelMapToRoundedRect(int resId, int topLeft, int topRigth, int bottomRight, int bottomLeft) {
+ setPixelMap(resId);
+ setClipGravity(GRAVITY_CENTER);
+ setCornerRadii(new float[]{topLeft, topLeft, topRigth, topRigth, bottomRight, bottomRight, bottomLeft, bottomLeft});
+ setScaleMode(ScaleMode.CLIP_CENTER);
+ }
+
+ /**
+ * 图片显示圆角
+ *
+ * @param fileDescriptor 图像源文件的描述符
+ * @param topLeft 左上圆角半径
+ * @param topRigth 右上圆角半径
+ * @param bottomRight 右下圆角半径
+ * @param bottomLeft 左下圆角半径
+ */
+ public void setPixelMapToRoundedRect(FileDescriptor fileDescriptor, int topLeft, int topRigth, int bottomRight, int bottomLeft) {
+ setPixelMap(getPixelMap(fileDescriptor));
+ setClipGravity(GRAVITY_CENTER);
+ setCornerRadii(new float[]{topLeft, topLeft, topRigth, topRigth, bottomRight, bottomRight, bottomLeft, bottomLeft});
+ setScaleMode(ScaleMode.CLIP_CENTER);
+ }
+
+ private void createCircleImage() {
+ if (holder != null) {
+ this.addDrawTask(new DrawTask() {
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ float centerX = getWidth() / 2f;
+ float centerY = getHeight() / 2f;
+ float radius = Math.min(centerX, centerY);
+ Paint paint = new Paint();
+ Shader shader = new PixelMapShader(holder, Shader.TileMode.CLAMP_TILEMODE, Shader.TileMode.CLAMP_TILEMODE);
+ paint.setShader(shader, Paint.ShaderType.SWEEP_SHADER);
+ canvas.drawCircle(centerX, centerY, radius, paint);
+ }
+ });
+ }
+ }
+
+ private void createOvalImage(){
+ this.addDrawTask(new DrawTask() {
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ Paint paint = new Paint();
+ Shader shader = new PixelMapShader(holder, Shader.TileMode.CLAMP_TILEMODE, Shader.TileMode.CLAMP_TILEMODE);
+ paint.setShader(shader, Paint.ShaderType.SWEEP_SHADER);
+ PixelMap pixelMap = holder.getPixelMap();
+ int min = Math.min(pixelMap.getImageInfo().size.width, pixelMap.getImageInfo().size.height);
+ int radiusX = Math.min(min, minImageLength);
+ float halfRadiusX = radiusX / 2f;
+ float quarterRadiusX = radiusX / 4f;
+ float left = getWidth() / 2f - halfRadiusX;
+ float right = getWidth() / 2f + halfRadiusX;
+ float top = getHeight() / 2f - quarterRadiusX;
+ float bottom = getHeight() / 2f + quarterRadiusX;
+ RectFloat rect = new RectFloat(left, top, right, bottom);
+ canvas.drawOval(rect, paint);
+ }
+ });
+ }
+
+ private void initVariable(PixelMap pixelMap) {
+ if (pixelMap != null) {
+ holder = new PixelMapHolder(pixelMap);
+ minImageLength = Math.min(getWidth(), getHeight());
+ }
+ }
+
+ private PixelMap getPixelMap(int resId) {
+ try (InputStream inputStream = getResourceManager().getResource(resId)) {
+ ImageSource imageSource = ImageSource.create(inputStream, null);
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.desiredSize = new Size(getWidth(), getHeight());
+ decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
+ return imageSource.createPixelmap(decodingOpts);
+ } catch (Exception e) {
+ HiLog.error(LABEL, "exception");
+ return null;
+ }
+ }
+
+ private PixelMap getPixelMap(FileDescriptor fileDescriptor) {
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.desiredSize = new Size(getWidth(), getHeight());
+ decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
+ ImageSource imageSource = ImageSource.create(fileDescriptor, null);
+ return imageSource.createThumbnailPixelmap(decodingOpts, true);
+ }
+}
diff --git a/012.RoundedImage_OpenHarmony-master/library/src/main/resources/base/element/string.json b/012.RoundedImage_OpenHarmony-master/library/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e2b219ccdd1183e23968586e5e2e404b41c38c9
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/library/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "library"
+ }
+ ]
+}
diff --git a/012.RoundedImage_OpenHarmony-master/settings.gradle b/012.RoundedImage_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..d0c7ee8440156d4a9324ac5357770747425fef57
--- /dev/null
+++ b/012.RoundedImage_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':library'
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.gitignore b/013.MaterialProgressBar_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.idea/.gitignore b/013.MaterialProgressBar_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.idea/compiler.xml b/013.MaterialProgressBar_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.idea/gradle.xml b/013.MaterialProgressBar_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f0b6549e50dad37933cc5898dc35391764feb555
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.idea/jarRepositories.xml b/013.MaterialProgressBar_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.idea/misc.xml b/013.MaterialProgressBar_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_413041523.json b/013.MaterialProgressBar_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_413041523.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_413041523.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/.idea/previewer/previewConfig.json b/013.MaterialProgressBar_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..dadbec833346175df46e7c55a3f0573d38b584e5
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,9 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\workspace\\MyApplication4\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git "a/013.MaterialProgressBar_OpenHarmony-master/013\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204MaterialProgressBar\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/013.MaterialProgressBar_OpenHarmony-master/013\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204MaterialProgressBar\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..f65f162801b57fef9d7b2b4c7f88fef54a6ad894
Binary files /dev/null and "b/013.MaterialProgressBar_OpenHarmony-master/013\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204MaterialProgressBar\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/013.MaterialProgressBar_OpenHarmony-master/build.gradle b/013.MaterialProgressBar_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..613f3e6a0b18b7a502df3b3655e61411ae191520
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/.gitignore b/013.MaterialProgressBar_OpenHarmony-master/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/build.gradle b/013.MaterialProgressBar_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5b676898b964683517e5275b9d2f77aaf52ceed2
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 3
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/libs/materialprogressbarohoslibrary-debug.har b/013.MaterialProgressBar_OpenHarmony-master/entry/libs/materialprogressbarohoslibrary-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..945c8e7be477cf84ae9929fcf92f8ebc914e41a1
Binary files /dev/null and b/013.MaterialProgressBar_OpenHarmony-master/entry/libs/materialprogressbarohoslibrary-debug.har differ
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/config.json b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..28201c2a2b89dcb36d6ea5fae6f31378bce26507
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication4",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 3,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.myapplication4",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.myapplication4.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/MainAbility.java b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..31d3c7558cfbc762f96c05db47ae750c4f8ed395
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.myapplication4;
+
+import com.example.myapplication4.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/MyApplication.java b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..06869a8cedf3c0cfa5bcb64b037f85bc3d9f5fb7
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.myapplication4;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/slice/MainAbilitySlice.java b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..e146c4c001499fd24624b7ab0ef7ab532c75550a
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/java/com/example/myapplication4/slice/MainAbilitySlice.java
@@ -0,0 +1,89 @@
+package com.example.myapplication4.slice;
+
+
+
+import com.example.materialprogressbarohoslibrary.CircleProgress;
+import com.example.materialprogressbarohoslibrary.CircleProgressDrawTask;
+import com.example.materialprogressbarohoslibrary.LineProgress;
+import com.example.materialprogressbarohoslibrary.LineProgressDrawTask;
+import com.example.myapplication4.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.ProgressBar;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+
+
+public class MainAbilitySlice extends AbilitySlice {
+
+ public EventHandler handler = new EventHandler(EventRunner.create(true));
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ Component button1 = findComponentById(ResourceTable.Id_button1);
+ Component button2 = findComponentById(ResourceTable.Id_button2);
+ Component button3 = findComponentById(ResourceTable.Id_button3);
+ Component button4 = findComponentById(ResourceTable.Id_button4);
+ Component button5 = findComponentById(ResourceTable.Id_button5);
+ Component button6 = findComponentById(ResourceTable.Id_button6);
+ ProgressBar progressBar = (ProgressBar) findComponentById(ResourceTable.Id_progressBar);
+
+ LineProgressDrawTask lineProgressDrawTask = new LineProgressDrawTask(button1);
+ LineProgressDrawTask lineProgressDrawTask2 = new LineProgressDrawTask(button2);
+ LineProgressDrawTask lineProgressDrawTask3 = new LineProgressDrawTask(button3);
+ lineProgressDrawTask.setCurrentValue(50);
+
+ LineProgress lineProgress = new LineProgress(this);
+ lineProgress.setStartNum(2);
+ lineProgress.SetMoreAnimator(lineProgressDrawTask2,100,200);
+ lineProgress.SetMoreAnimator(lineProgressDrawTask3,100,200);
+ lineProgress.SetMoreAnimator2(lineProgressDrawTask3,100,200);
+
+ CircleProgressDrawTask mDrawTask = new CircleProgressDrawTask(button4);
+ mDrawTask.setMaxValue(100);
+ mDrawTask.setCurrentValue(75);
+ CircleProgressDrawTask mDrawTask2 = new CircleProgressDrawTask(button5);
+ mDrawTask.setMaxValue(100);
+ CircleProgressDrawTask mDrawTask3 = new CircleProgressDrawTask(button6);
+ mDrawTask.setMaxValue(100);
+
+ CircleProgress circleProgress = new CircleProgress(this);
+ circleProgress.SetMoreAnimator(mDrawTask2,100,200);
+ circleProgress.SetMoreAnimator(mDrawTask3,100,200);
+ circleProgress.SetMoreAnimator2(mDrawTask3,100,200);
+
+ handler.postTask(new Runnable() {
+ int i = 0;
+ @Override
+ public void run() {
+ i = i + 1;
+ getUITaskDispatcher().asyncDispatch(new Runnable(){
+ @Override
+ public void run() {
+ if( i <= mDrawTask.getMaxValue()) {
+ progressBar.setProgressValue(i);
+
+ } else {
+ progressBar.setProgressValue(0);
+ i = 0;
+ }
+ }
+ });
+ handler.postTask(this, 100);
+ }
+ }, 200);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..30a3e3fbc336c87b719eea585e3bdd8a3deeab0f
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication4"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_active.xml b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_active.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6559b75fa383b2d92545d331fed3d603a6030d28
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_active.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9b394a278e8e869d1bac126125fdf58e06345981
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/013.MaterialProgressBar_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/013.MaterialProgressBar_OpenHarmony-master/entry/src/test/java/com/example/myapplication4/ExampleTest.java b/013.MaterialProgressBar_OpenHarmony-master/entry/src/test/java/com/example/myapplication4/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..df80ecb11426cca15c2e78fdf4b0e215152e5a69
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/entry/src/test/java/com/example/myapplication4/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.myapplication4;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/013.MaterialProgressBar_OpenHarmony-master/gradle.properties b/013.MaterialProgressBar_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/013.MaterialProgressBar_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/013.MaterialProgressBar_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/013.MaterialProgressBar_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/013.MaterialProgressBar_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/013.MaterialProgressBar_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/013.MaterialProgressBar_OpenHarmony-master/gradlew b/013.MaterialProgressBar_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/013.MaterialProgressBar_OpenHarmony-master/gradlew.bat b/013.MaterialProgressBar_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/013.MaterialProgressBar_OpenHarmony-master/settings.gradle b/013.MaterialProgressBar_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07
--- /dev/null
+++ b/013.MaterialProgressBar_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry'
diff --git a/014.CircleImageView_OpenHarmony-master/.gitignore b/014.CircleImageView_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/.gitignore b/014.CircleImageView_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/compiler.xml b/014.CircleImageView_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/gradle.xml b/014.CircleImageView_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aa73eb2a21b3f5f07d00e5c304596792141b689a
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/jarRepositories.xml b/014.CircleImageView_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/misc.xml b/014.CircleImageView_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1514610214.json b/014.CircleImageView_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1514610214.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1514610214.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-623666282.json b/014.CircleImageView_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-623666282.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-623666282.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/previewer/previewConfig.json b/014.CircleImageView_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..3cdfe65af2cdda0ad5ab14b9f072f49702c525af
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,10 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\ThirdParty\\CircleImageView_HarmonyOS\\entry": [],
+ "D:\\PCFile\\PCFile\\svn\\017.CircleImageView\\CircleImageView_HarmonyOS\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/.idea/vcs.xml b/014.CircleImageView_OpenHarmony-master/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2bdec2d71b6a5ce4ae49efc37516809c50e4d5e
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/014.CircleImageView_OpenHarmony-master/014\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204CircleImageView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/014.CircleImageView_OpenHarmony-master/014\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204CircleImageView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..f5574592e0a956b50322d3b6526d51d2b6cc69a3
Binary files /dev/null and "b/014.CircleImageView_OpenHarmony-master/014\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204CircleImageView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/014.CircleImageView_OpenHarmony-master/build.gradle b/014.CircleImageView_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0da9bc913f7350fad9087d8535f200bedce92ed3
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/014.CircleImageView_OpenHarmony-master/circleimageview/.gitignore b/014.CircleImageView_OpenHarmony-master/circleimageview/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/circleimageview/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/014.CircleImageView_OpenHarmony-master/circleimageview/build.gradle b/014.CircleImageView_OpenHarmony-master/circleimageview/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/circleimageview/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/config.json b/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..3d87300310fa9bc76c727060e9f32c7dd3dc9333
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.circleimageview_harmonyos",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.circleimageview",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "circleimageview",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/java/com/isoftstone/circleimageview/CircleImageView.java b/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/java/com/isoftstone/circleimageview/CircleImageView.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a62f92be33a08db222341b635753e4cc064c389
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/java/com/isoftstone/circleimageview/CircleImageView.java
@@ -0,0 +1,466 @@
+package com.isoftstone.circleimageview;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.components.element.Element;
+import ohos.agp.render.*;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.Matrix;
+import ohos.agp.utils.RectFloat;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+import ohos.media.image.common.PixelFormat;
+import ohos.media.image.common.Rect;
+import ohos.media.image.common.Size;
+import ohos.multimodalinput.event.MmiPoint;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.io.InputStream;
+
+public class CircleImageView extends Image implements Image.DrawTask, Image.TouchEventListener,Image.LayoutRefreshedListener{
+ private static HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x000110, "CircleImageView");
+ private static final ScaleMode SCALE_MODE = ScaleMode.CLIP_CENTER;
+ private PixelMap mPixelMap;
+ private final RectFloat mDrawableRect = new RectFloat();
+ private final RectFloat mBorderRect = new RectFloat();
+ private final Matrix mShaderMatrix = new Matrix();
+ //图片画笔
+ private final Paint mPixelMapPaint = new Paint();
+ //边界画笔
+ private final Paint mBorderPaint = new Paint();
+ //圆环背景画笔
+ private final Paint mCircleBackgroundPaint = new Paint();
+ private PixelMapShader mPixelMapShader = new PixelMapShader();
+ private static final int DEFAULT_BORDER_WIDTH = 10;
+ private static final Color DEFAULT_BORDER_COLOR = Color.BLACK;
+ private static final Color DEFAULT_CIRCLE_BACKGROUND_COLOR = Color.TRANSPARENT;
+ private static final float DEFAULT_IMAGE_ALPHA = 1.0f;
+ private static final boolean DEFAULT_BORDER_OVERLAY = false;
+ //边框颜色 civ_border_color
+ private Color mBorderColor = DEFAULT_BORDER_COLOR;
+ //边框宽度 civ_border_width
+ private int mBorderWidth = DEFAULT_BORDER_WIDTH;
+ //背景圆颜色 civ_circle_background_color
+ private Color mCircleBackgroundColor = DEFAULT_CIRCLE_BACKGROUND_COLOR;
+ //是否允许圆图压住圆环 civ_border_overlay
+ private boolean mBorderOverlay;
+ private float mImageAlpha = DEFAULT_IMAGE_ALPHA;
+ private ColorFilter mColorFilter;
+ private boolean mRebuildShader;
+ private float mDrawableRadius;
+ private float mBorderRadius;
+ private boolean mDisableCircularTransformation;
+ // private Canvas mBitmapCanvas;
+ private boolean mInitialized;
+ private PixelMapHolder pixelMapHolder;//像素图片持有者
+
+ public CircleImageView(Context context) {
+ super(context);
+ HiLog.info(label, "Log_单参构造");
+ init();
+ //设置TouchEvent监听
+ setTouchEventListener(this::onTouchEvent);
+ //设置LayoutRefreshed监听
+ setLayoutRefreshedListener(this::onRefreshed);
+ }
+
+ public CircleImageView(Context context, AttrSet attrSet) {
+ this(context, attrSet, null);
+ HiLog.info(label, "Log_xml构造");
+ }
+
+ public CircleImageView(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ //获取xml中设置的自定义属性值
+ mBorderWidth = attrSet.getAttr("civ_border_width").get().getIntegerValue();
+ mBorderColor = attrSet.getAttr("civ_border_color").get().getColorValue();
+ mBorderOverlay = attrSet.getAttr("civ_border_overlay").get().getBoolValue();
+ mCircleBackgroundColor = attrSet.getAttr("civ_circle_background_color").get().getColorValue();
+
+ init();
+ //设置TouchEvent监听
+ setTouchEventListener(this::onTouchEvent);
+ //设置Refreshed监听
+ setLayoutRefreshedListener(this::onRefreshed);
+ }
+
+ @Override
+ public void invalidate() {
+ //添加绘制任务
+ addDrawTask(this::onDraw);
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ //绘制背景圆
+ if (mCircleBackgroundColor != Color.TRANSPARENT) {
+ canvas.drawCircle(mDrawableRect.getHorizontalCenter(), mDrawableRect.getVerticalCenter(),
+ mDrawableRadius, mCircleBackgroundPaint);
+ }
+ //绘制边框
+ if (mBorderWidth > 0) {
+ canvas.drawCircle(mBorderRect.getHorizontalCenter(), mBorderRect.getVerticalCenter(),
+ mBorderRadius, mBorderPaint);
+ }
+
+ if (pixelMapHolder == null) {
+ return;
+ }
+
+ synchronized (pixelMapHolder) {
+ // 绘制图片,使用之前计算的数据
+ if (mRebuildShader) {
+ mRebuildShader = false;
+ PixelMapShader bitmapShader = new PixelMapShader(pixelMapHolder, Shader.TileMode.CLAMP_TILEMODE,
+ Shader.TileMode.CLAMP_TILEMODE);
+ bitmapShader.setShaderMatrix(mShaderMatrix);
+ mPixelMapPaint.setShader(bitmapShader, Paint.ShaderType.PIXELMAP_SHADER);
+ }
+ HiLog.info(label, "Log_圆图绘制");
+ canvas.drawCircle(mDrawableRect.getHorizontalCenter(), mDrawableRect.getVerticalCenter(), mDrawableRadius,
+ mPixelMapPaint);
+ // 手动置null有问题
+ //pixelMapHolder = null;
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ HiLog.info(label, "Log_onTouchEvent");
+ if (mDisableCircularTransformation) {
+ return super.getTouchEventListener().onTouchEvent(component, touchEvent);
+ }
+ //获取点信息
+ MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
+ return inTouchableArea(point) && super.getTouchEventListener().onTouchEvent(component, touchEvent);
+ }
+
+ @Override
+ public void onRefreshed(Component component) {
+ HiLog.info(label, "Log_onRefreshed");
+ updateDimensions();
+ invalidate();
+ }
+
+ @Override
+ public void setPadding(int left, int top, int right, int bottom) {
+ super.setPadding(left, top, right, bottom);
+ updateDimensions();
+ invalidate();
+ }
+
+ @Override
+ public void setPaddingRelative(int start, int top, int end, int bottom) {
+ super.setPaddingRelative(start, top, end, bottom);
+ updateDimensions();
+ invalidate();
+ }
+
+ //由于有缩放所以需要计算是否在缩放后的范围内
+ private boolean inTouchableArea(MmiPoint point) {
+ if (mBorderRect.isEmpty()) {
+ return true;
+ }
+
+ return Math.pow(point.getX() - mBorderRect.getHorizontalCenter(), 2) + Math.pow(point.getY() - mBorderRect.getVerticalCenter(), 2) <= Math.pow(mBorderRadius, 2);
+ }
+
+ //三个画笔设置
+ private void init() {
+ mInitialized = true;
+ HiLog.info(label, "Log_init");
+ super.setScaleMode(SCALE_MODE);
+
+ mPixelMapPaint.setAntiAlias(true);
+ mPixelMapPaint.setDither(true);
+ mPixelMapPaint.setFilterBitmap(true);
+ mPixelMapPaint.setAlpha(mImageAlpha);
+ mPixelMapPaint.setColorFilter(mColorFilter);
+
+ mBorderPaint.setStyle(Paint.Style.STROKE_STYLE);
+ mBorderPaint.setAntiAlias(true);
+ mBorderPaint.setColor(mBorderColor);
+ mBorderPaint.setStrokeWidth(mBorderWidth);
+
+ mCircleBackgroundPaint.setStyle(Paint.Style.FILL_STYLE);
+ mCircleBackgroundPaint.setAntiAlias(true);
+ mCircleBackgroundPaint.setColor(mCircleBackgroundColor);
+ }
+
+ /**
+ * 获取原有Image中的位图资源后重新设置PixelMapHolder
+ */
+ private void initializePixelMap() {
+ HiLog.info(label, "initializePixelMap");
+ if (mPixelMap != null) {
+ pixelMapHolder = new PixelMapHolder(mPixelMap);
+ if (mInitialized) {
+ updateShaderMatrix();
+ }
+ invalidate();//重新检验该组件
+ } else {
+ HiLog.info(label, "Log_mPixelMapNULL");
+ pixelMapHolder = null;
+ }
+ }
+
+ /**
+ * 通过资源ID获取位图对象
+ **/
+ private PixelMap getPixelMap(int resId) {
+ InputStream drawableInputStream = null;
+ try {
+ drawableInputStream = getResourceManager().getResource(resId);
+ ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
+ sourceOptions.formatHint = "image/png";
+ ImageSource imageSource = ImageSource.create(drawableInputStream, null);
+ ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
+ decodingOptions.desiredSize = new Size(0, 0);
+ decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
+ decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
+ PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
+ return pixelMap;
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (drawableInputStream != null) {
+ drawableInputStream.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ //在设置图片时获取图片资源解码为无压缩的位图格式
+ @Override
+ public void setPixelMap(PixelMap pixelMap) {
+ // super.setPixelMap(pixelMap);
+ HiLog.info(label, "Log_setPixelMap");
+ mPixelMap = pixelMap;
+ initializePixelMap();
+ }
+
+ @Override
+ public void setImageAndDecodeBounds(int resId) {
+ // super.setImageAndDecodeBounds(resId);
+ mPixelMap = getPixelMap(resId);
+ initializePixelMap();
+ HiLog.info(label, "Log_setImageAndDecodeBounds");
+ }
+
+ @Override
+ public void setImageElement(Element element) {
+ // super.setImageElement(element);
+ //TODO
+ mPixelMap = getPixelMap();
+ initializePixelMap();
+ HiLog.info(label, "Log_setImageElement");
+ }
+
+ //布局变化时重新计算画布范围
+ private void updateDimensions() {
+ HiLog.info(label, "Log_updateDimensions");
+ mBorderRect.modify(calculateBounds());
+ mBorderRadius = Math.min((mBorderRect.getHeight() - mBorderWidth) / 2.0f, (mBorderRect.getWidth() - mBorderWidth) / 2.0f);
+ mDrawableRect.modify(mBorderRect);
+ //图片不能压住圆环并且边框宽度不为0则将图片缩小
+ if (!mBorderOverlay && mBorderWidth > 0) {
+ HiLog.info(label, "Log_shouldinSet");
+ mDrawableRect.shrink(mBorderWidth - 1.0f, mBorderWidth - 1.0f);
+ }
+ mDrawableRadius = Math.min(mDrawableRect.getHeight() / 2.0f, mDrawableRect.getWidth() / 2.0f);
+ updateShaderMatrix();
+ }
+
+ private RectFloat calculateBounds() {
+ int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
+ int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+
+ int sideLength = Math.min(availableWidth, availableHeight);
+
+ float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;
+ float top = getPaddingTop() + (availableHeight - sideLength) / 2f;
+
+ return new RectFloat(left, top, left + sideLength, top + sideLength);
+ }
+
+ public Color getBorderColor() {
+ return mBorderColor;
+ }
+
+ public void setBorderColor(Color borderColor) {
+ HiLog.info(label,"Log_setBorderColor");
+ if (borderColor == mBorderColor) {
+ return;
+ }
+
+ mBorderColor = borderColor;
+ mBorderPaint.setColor(borderColor);
+ invalidate();
+ }
+
+ public Color getCircleBackgroundColor() {
+ return mCircleBackgroundColor;
+ }
+
+ public void setCircleBackgroundColor( Color circleBackgroundColor) {
+ if (circleBackgroundColor == mCircleBackgroundColor) {
+ return;
+ }
+
+ mCircleBackgroundColor = circleBackgroundColor;
+ mCircleBackgroundPaint.setColor(circleBackgroundColor);
+ invalidate();
+ }
+
+ public int getBorderWidth() {
+ return mBorderWidth;
+ }
+
+ public void setBorderWidth(int borderWidth) {
+ if (borderWidth == mBorderWidth) {
+ return;
+ }
+
+ mBorderWidth = borderWidth;
+ mBorderPaint.setStrokeWidth(borderWidth);
+ updateDimensions();
+ invalidate();
+ }
+
+ public boolean isBorderOverlay() {
+ return mBorderOverlay;
+ }
+
+ public void setBorderOverlay(boolean borderOverlay) {
+ if (borderOverlay == mBorderOverlay) {
+ return;
+ }
+ mBorderOverlay = borderOverlay;
+ updateDimensions();
+ invalidate();
+ }
+
+ public boolean isDisableCircularTransformation() {
+ return mDisableCircularTransformation;
+ }
+
+ public void setDisableCircularTransformation(boolean disableCircularTransformation) {
+ if (disableCircularTransformation == mDisableCircularTransformation) {
+ return;
+ }
+
+ mDisableCircularTransformation = disableCircularTransformation;
+
+ if (disableCircularTransformation) {
+ mPixelMap = null;
+ // mBitmapCanvas = null;
+ mPixelMapPaint.setShader(null,null);
+ } else {
+ initializePixelMap();
+ }
+
+ invalidate();
+ }
+
+
+ @Override
+ public float getAlpha() {
+ return mImageAlpha;
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+
+ if (alpha == mImageAlpha) {
+ return;
+ }
+
+ mImageAlpha = alpha;
+
+ // This might be called during ImageView construction before
+ // member initialization has finished on API level >= 16.
+ if (mInitialized) {
+ mPixelMapPaint.setAlpha(alpha);
+ invalidate();
+ }
+ super.setAlpha(alpha);
+ }
+
+ public void setColorFilter(ColorFilter cf) {
+ if (cf == mColorFilter) {
+ return;
+ }
+
+ mColorFilter = cf;
+
+ if (mInitialized) {
+ mPixelMapPaint.setColorFilter(cf);
+ invalidate();
+ }
+ }
+
+
+ public ColorFilter getColorFilter() {
+ return mColorFilter;
+ }
+
+
+ @Override
+ public ScaledListener getScaledListener() {
+ HiLog.info(label, "Log_getScaledListener");
+ updateDimensions();
+ invalidate();//重新检验该组件
+ return super.getScaledListener();
+ }
+
+ @Override
+ public LayoutRefreshedListener getLayoutRefreshedListener() {
+ HiLog.info(label, "Log_getLayoutRefreshedListener");
+ updateDimensions();
+ invalidate();//重新检验该组件
+ return super.getLayoutRefreshedListener();
+ }
+
+ /**
+ * 这个函数为获取pixelMapShader的Matrix参数,设置最小缩放比例,平移参数。
+ * 作用:保证图片损失度最小和始终绘制图片正中央的那部分
+ */
+ private void updateShaderMatrix() {
+ // mPixelMap = getPixelMap();
+ if (mPixelMap == null) {
+ HiLog.info(label, "Log_mPixelMapNULL");
+ return;
+ }
+
+ float scale;
+ float dx = 0;
+ float dy = 0;
+
+ mShaderMatrix.setMatrix(null);
+
+ int pixelMapHeight = mPixelMap.getImageInfo().size.height;
+ int pixelMapWidth = mPixelMap.getImageInfo().size.height;
+
+ if (pixelMapWidth * mDrawableRect.getHeight() > mDrawableRect.getWidth() * pixelMapHeight) {
+ scale = mDrawableRect.getHeight() / (float) pixelMapHeight;
+ dx = (mDrawableRect.getWidth() - pixelMapWidth * scale) * 0.5f;
+ } else {
+ scale = mDrawableRect.getWidth() / (float) pixelMapWidth;
+ dy = (mDrawableRect.getHeight() - pixelMapHeight * scale) * 0.5f;
+ }
+
+ mShaderMatrix.setScale(scale, scale);
+ mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
+ HiLog.info(label, "Log_mPixelMapEND");
+ mRebuildShader = true;
+ }
+
+}
diff --git a/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/resources/base/element/string.json b/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..67972943c97d9af03a6be089b8a8aa02c56b9cec
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/circleimageview/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "CircleImageView"
+ }
+ ]
+}
diff --git a/014.CircleImageView_OpenHarmony-master/entry/.gitignore b/014.CircleImageView_OpenHarmony-master/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/014.CircleImageView_OpenHarmony-master/entry/build.gradle b/014.CircleImageView_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..d1e4cf3570140636d8ce7739b0a95e8aa55d2b9c
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ compile project(path: ':circleimageview')
+}
diff --git a/014.CircleImageView_OpenHarmony-master/entry/libs/circleimageview-debug.har b/014.CircleImageView_OpenHarmony-master/entry/libs/circleimageview-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..f9754023e65cf1d1da093c20123822b5b1a43129
Binary files /dev/null and b/014.CircleImageView_OpenHarmony-master/entry/libs/circleimageview-debug.har differ
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/config.json b/014.CircleImageView_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..72763d8e654e5dd619dd62c4599d69d7a707ea5f
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.circleimageview_harmonyos",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.circleimageview_harmonyos",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.isoftstone.circleimageview_harmonyos.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/MainAbility.java b/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..7de80e9c03ca0d603ad0392ac45ecd3645c091c5
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/MainAbility.java
@@ -0,0 +1,13 @@
+package com.isoftstone.circleimageview_harmonyos;
+
+import com.isoftstone.circleimageview_harmonyos.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/MyApplication.java b/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b6777cf679108238f4d755b87e9af8f66e8bf15
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/MyApplication.java
@@ -0,0 +1,10 @@
+package com.isoftstone.circleimageview_harmonyos;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/slice/MainAbilitySlice.java b/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..a818c85fa14b1de54573285b0012d14255e66d05
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/main/java/com/isoftstone/circleimageview_harmonyos/slice/MainAbilitySlice.java
@@ -0,0 +1,27 @@
+package com.isoftstone.circleimageview_harmonyos.slice;
+
+import com.isoftstone.circleimageview.CircleImageView;
+import com.isoftstone.circleimageview_harmonyos.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+
+public class MainAbilitySlice extends AbilitySlice {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ CircleImageView imageView = (CircleImageView) findComponentById(ResourceTable.Id_image);
+ imageView.setImageAndDecodeBounds(ResourceTable.Media_hugh);
+
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..b72f87d64fe8aeb8a121f90ed00b4b7464d1395c
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "CircleImageView_HarmonyOS"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6f3398301a9f007e7386b1fa902eda21ef8be54f
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/media/hugh.png b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/media/hugh.png
new file mode 100644
index 0000000000000000000000000000000000000000..94c0857e66f4fbacc2996e748d42f69a5ecc7c49
Binary files /dev/null and b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/media/hugh.png differ
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/014.CircleImageView_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/014.CircleImageView_OpenHarmony-master/entry/src/test/java/com/isoftstone/circleimageview_harmonyos/ExampleTest.java b/014.CircleImageView_OpenHarmony-master/entry/src/test/java/com/isoftstone/circleimageview_harmonyos/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ccb487b2a8a8c3732559928b6c0b052c28c652c
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/entry/src/test/java/com/isoftstone/circleimageview_harmonyos/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.isoftstone.circleimageview_harmonyos;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/014.CircleImageView_OpenHarmony-master/gradle.properties b/014.CircleImageView_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/014.CircleImageView_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/014.CircleImageView_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/014.CircleImageView_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/014.CircleImageView_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/014.CircleImageView_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/014.CircleImageView_OpenHarmony-master/gradlew b/014.CircleImageView_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/014.CircleImageView_OpenHarmony-master/gradlew.bat b/014.CircleImageView_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/014.CircleImageView_OpenHarmony-master/settings.gradle b/014.CircleImageView_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..6d8d23c858232122d0836f7085ab66cf871e6a4c
--- /dev/null
+++ b/014.CircleImageView_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':circleimageview'
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.gitignore b/015.AndroidViewAnimations_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.idea/.gitignore b/015.AndroidViewAnimations_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.idea/compiler.xml b/015.AndroidViewAnimations_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.idea/gradle.xml b/015.AndroidViewAnimations_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..31587e7de0c1831ca2b77b2d37ee629d318173b5
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.idea/jarRepositories.xml b/015.AndroidViewAnimations_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.idea/misc.xml b/015.AndroidViewAnimations_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..58918f50335428f2efb3af4d621f9f405ed659d4
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_894669568.json b/015.AndroidViewAnimations_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_894669568.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_894669568.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/.idea/previewer/previewConfig.json b/015.AndroidViewAnimations_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..4e84aa2fc3d9a40e3d6b66b3853363356766bfd6
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,9 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\PCFile\\PCFile\\svn\\036.AndroidViewAnimations\\HarmonyAnimations\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git "a/015.AndroidViewAnimations_OpenHarmony-master/015.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204animations\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/015.AndroidViewAnimations_OpenHarmony-master/015.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204animations\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..6f565d4894d0f5b514a44112b2263ec1aa5857a6
Binary files /dev/null and "b/015.AndroidViewAnimations_OpenHarmony-master/015.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204animations\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/build.gradle b/015.AndroidViewAnimations_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0da9bc913f7350fad9087d8535f200bedce92ed3
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/.gitignore b/015.AndroidViewAnimations_OpenHarmony-master/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/build.gradle b/015.AndroidViewAnimations_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..f34a993791daeab18ed82fae3089f7daf7eac777
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ compile project(path: ':library')
+}
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/config.json b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..bc9ab0e63960a74441e78dd0c502540768fd6dcc
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,49 @@
+{
+ "app": {
+ "bundleName": "com.example.animations",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.animations",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.animations.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:label_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/MainAbility.java b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d7d5fa2aa90a4e18467d601c39ce2d81fab7a31
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/MainAbility.java
@@ -0,0 +1,19 @@
+package com.example.animations;
+
+import com.example.animations.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+/**
+ * Ability
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/MyApplication.java b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..6daf80f425cf05351fbbfa7a1a1fb04300613058
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/MyApplication.java
@@ -0,0 +1,16 @@
+package com.example.animations;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * application
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/slice/MainAbilitySlice.java b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..f0c33db2a6e42228528afc55c93691c1d7d2be43
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/slice/MainAbilitySlice.java
@@ -0,0 +1,122 @@
+package com.example.animations.slice;
+
+import com.example.animations.ResourceTable;
+import com.isoftstone.library.BaseAnimation;
+import com.isoftstone.library.impl.BounceAnimation;
+import com.isoftstone.library.impl.FlashAnimation;
+import com.isoftstone.library.impl.PulseAnimation;
+import com.isoftstone.library.impl.RotateAnimation;
+import com.isoftstone.library.impl.RubberBandAnimation;
+import com.isoftstone.library.impl.ShakeAnimation;
+import com.isoftstone.library.impl.WobbleAnimation;
+import com.isoftstone.library.impl.fade.FadeInAnimation;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Text;
+import ohos.agp.components.TextField;
+
+/**
+ * Slice
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class MainAbilitySlice extends AbilitySlice {
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ TextField textField1 = (TextField) findComponentById(ResourceTable.Id_textField1);
+ TextField textField2 = (TextField) findComponentById(ResourceTable.Id_textField2);
+ Text text = (Text) findComponentById(ResourceTable.Id_text);
+ Button button1 = (Button) findComponentById(ResourceTable.Id_button1);
+ button1.setClickedListener(component -> {
+ BaseAnimation shake = new ShakeAnimation(); // 左右抖动
+ shake.startAnimation(textField1);
+ shake.startAnimation(textField2);
+ text.setText(ResourceTable.String_error_message);
+ BaseAnimation fadeIn = new FadeInAnimation();
+ fadeIn.startAnimation(text);
+ });
+
+ Button button2 = (Button) findComponentById(ResourceTable.Id_button2);
+ button2.setClickedListener(component -> {
+ BaseAnimation rotate = new RotateAnimation(); // 按一定角度旋转抖动
+ rotate.startAnimation(textField1);
+ rotate.startAnimation(textField2);
+ text.setText(ResourceTable.String_error_message);
+ BaseAnimation fadeIn = new FadeInAnimation();
+ fadeIn.startAnimation(text);
+ });
+
+ Button button3 = (Button) findComponentById(ResourceTable.Id_button3);
+ button3.setClickedListener(component -> {
+ BaseAnimation flash = new FlashAnimation(); // 透明-不透明之间变化
+ flash.startAnimation(textField1);
+ flash.startAnimation(textField2);
+ text.setText(ResourceTable.String_error_message);
+ BaseAnimation fadeIn = new FadeInAnimation();
+ fadeIn.startAnimation(text);
+ });
+
+ Button button4 = (Button) findComponentById(ResourceTable.Id_button4);
+ button4.setClickedListener(component -> {
+ BaseAnimation pulse = new PulseAnimation(); // 放大缩小
+ pulse.startAnimation(textField1);
+ pulse.startAnimation(textField2);
+ text.setText(ResourceTable.String_error_message);
+ BaseAnimation fadeIn = new FadeInAnimation();
+ fadeIn.startAnimation(text);
+ });
+
+ Button button5 = (Button) findComponentById(ResourceTable.Id_button5);
+ button5.setClickedListener(component -> {
+ BaseAnimation rubberBand = new RubberBandAnimation(); // 橡胶拉伸效果
+ rubberBand.startAnimation(textField1);
+ rubberBand.startAnimation(textField2);
+ text.setText(ResourceTable.String_error_message);
+ BaseAnimation fadeIn = new FadeInAnimation();
+ fadeIn.startAnimation(text);
+ });
+
+ Button button6 = (Button) findComponentById(ResourceTable.Id_button6);
+ button6.setClickedListener(component -> {
+ BaseAnimation bounce = new BounceAnimation(); // 弹跳
+ bounce.startAnimation(textField1);
+ bounce.startAnimation(textField2);
+ text.setText(ResourceTable.String_error_message);
+ BaseAnimation fadeIn = new FadeInAnimation();
+ fadeIn.startAnimation(text);
+ });
+
+ Button button7 = (Button) findComponentById(ResourceTable.Id_button7);
+ button7.setClickedListener(component -> {
+ BaseAnimation wobble = new WobbleAnimation(); // 摆动
+ wobble.startAnimation(textField1);
+ wobble.startAnimation(textField2);
+ text.setText(ResourceTable.String_error_message);
+ BaseAnimation fadeIn = new FadeInAnimation();
+ fadeIn.startAnimation(text);
+ });
+
+ Button button8 = (Button) findComponentById(ResourceTable.Id_button_next); // 页面跳转
+ button8.setClickedListener(component -> {
+ SecondAbilitySlice secondSlice = new SecondAbilitySlice();
+ Intent intent1 = new Intent();
+ present(secondSlice, intent1);
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/slice/SecondAbilitySlice.java b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/slice/SecondAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..2659012b37d6c916a73af468f9822fb358029077
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/java/com/example/animations/slice/SecondAbilitySlice.java
@@ -0,0 +1,90 @@
+package com.example.animations.slice;
+
+import com.example.animations.ResourceTable;
+import com.isoftstone.library.BaseAnimation;
+import com.isoftstone.library.impl.BounceAnimation;
+import com.isoftstone.library.impl.FlashAnimation;
+import com.isoftstone.library.impl.PulseAnimation;
+import com.isoftstone.library.impl.RotateAnimation;
+import com.isoftstone.library.impl.RubberBandAnimation;
+import com.isoftstone.library.impl.ShakeAnimation;
+import com.isoftstone.library.impl.WobbleAnimation;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Image;
+
+/**
+ * Slice
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class SecondAbilitySlice extends AbilitySlice {
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_second);
+
+ Image image = (Image) findComponentById(ResourceTable.Id_image);
+ Button button1 = (Button) findComponentById(ResourceTable.Id_button2_1);
+ button1.setClickedListener(component -> {
+ BaseAnimation shake = new ShakeAnimation(); // 左右抖动
+ shake.startAnimation(image);
+ });
+
+ Button button2 = (Button) findComponentById(ResourceTable.Id_button2_2);
+ button2.setClickedListener(component -> {
+ BaseAnimation rotate = new RotateAnimation(); // 按一定角度旋转抖动
+ rotate.startAnimation(image);
+ });
+
+ Button button3 = (Button) findComponentById(ResourceTable.Id_button2_3);
+ button3.setClickedListener(component -> {
+ BaseAnimation flash = new FlashAnimation(); // 透明-不透明之间变化
+ flash.startAnimation(image);
+ });
+
+ Button button4 = (Button) findComponentById(ResourceTable.Id_button2_4);
+ button4.setClickedListener(component -> {
+ BaseAnimation pulse = new PulseAnimation(); // 放大缩小
+ pulse.startAnimation(image);
+ });
+
+ Button button5 = (Button) findComponentById(ResourceTable.Id_button2_5);
+ button5.setClickedListener(component -> {
+ BaseAnimation rubberBand = new RubberBandAnimation(); // 橡胶拉伸效果
+ rubberBand.startAnimation(image);
+ });
+
+ Button button6 = (Button) findComponentById(ResourceTable.Id_button2_6);
+ button6.setClickedListener(component -> {
+ BaseAnimation bounce = new BounceAnimation(); // 弹跳
+ bounce.startAnimation(image);
+ });
+
+ Button button7 = (Button) findComponentById(ResourceTable.Id_button2_7);
+ button7.setClickedListener(component -> {
+ BaseAnimation wobble = new WobbleAnimation(); // 摆动
+ wobble.startAnimation(image);
+ });
+
+ Button button8 = (Button) findComponentById(ResourceTable.Id_button_other2);
+ button8.setClickedListener(component -> {
+ MainAbilitySlice mainSlice = new MainAbilitySlice();
+ Intent intent1 = new Intent();
+ present(mainSlice, intent1);
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..bbfef20791cbd40933aac0c1b09f20f0ae6a99fb
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,20 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "HarmonyAnimtions"
+ },
+ {
+ "name": "error_message",
+ "value": "Incorrect username or password !"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "label_name",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..80fca8cc4a8ded8e20576eb07c5494f42ce83e41
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button.xml b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..668c5c813c4e3cfe99445bcf4bddf1ec5e218235
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button_page.xml b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button_page.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9dfe2a55c7dfa212dab9bc9b9cfee8f7f43d2d40
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_button_page.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_text_field.xml b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_text_field.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9dfe2a55c7dfa212dab9bc9b9cfee8f7f43d2d40
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/graphic/background_text_field.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f5838d08dde31614ba5a046b6ebbb9ac96ddaa8b
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/layout/ability_second.xml b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/layout/ability_second.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5a097b0699d2fad6b1e278f0297ef58a5f2e126a
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/layout/ability_second.xml
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/media/photo.jpg b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/media/photo.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..5b2bd91e8997b3fbfaee05404572ab88a3d6ee90
Binary files /dev/null and b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/main/resources/base/media/photo.jpg differ
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/entry/src/test/java/com/example/animations/ExampleTest.java b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/test/java/com/example/animations/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f94290ba2ba08e5ef51d64b9431cddf985ffa73d
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/entry/src/test/java/com/example/animations/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.animations;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/gradle.properties b/015.AndroidViewAnimations_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/015.AndroidViewAnimations_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/015.AndroidViewAnimations_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/015.AndroidViewAnimations_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/gradlew b/015.AndroidViewAnimations_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/gradlew.bat b/015.AndroidViewAnimations_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/.gitignore b/015.AndroidViewAnimations_OpenHarmony-master/library/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/build.gradle b/015.AndroidViewAnimations_OpenHarmony-master/library/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/config.json b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..317504e8dae022b5f21194d12794efc27b8c9438
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.animations",
+ "vendor": "animation",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.animation.library",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "library",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/BaseAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/BaseAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccfc866f8434c3da88bac9c75061a0ade0b34a72
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/BaseAnimation.java
@@ -0,0 +1,24 @@
+package com.isoftstone.library;
+
+import ohos.agp.components.Component;
+
+/**
+ * 动画基础模板
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public interface BaseAnimation {
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ void startAnimation(Component component);
+
+ /**
+ * 停止动画
+ */
+ void stopAnimation();
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/BounceAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/BounceAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fe83566098243a13aea64c860ea3ba5cbe80f34
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/BounceAnimation.java
@@ -0,0 +1,60 @@
+package com.isoftstone.library.impl;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 弹跳效果
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class BounceAnimation implements BaseAnimation {
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_5 = 5L;
+
+ /**
+ * 移动距离
+ */
+ private static final float NUM_15 = 15f;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ float positionY = component.getContentPositionY();
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.moveToY(positionY).setDuration(DURATION_5);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.moveFromY(positionY - NUM_15).moveToY(positionY + NUM_15).setDuration(DURATION_5);
+ AnimatorProperty animator3 = component.createAnimatorProperty();
+ animator3.moveFromY(positionY + NUM_15).moveToY(positionY - NUM_15).setDuration(DURATION_5);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1,
+ animator2, animator3, animator2, animator3, animator2, animator3, animator2, animator1);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/FlashAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/FlashAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..436673684dc3b3700ec223355dfec5dee5b132ed
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/FlashAnimation.java
@@ -0,0 +1,63 @@
+package com.isoftstone.library.impl;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 透明至不透明变化
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class FlashAnimation implements BaseAnimation {
+
+ /**
+ * 透明度
+ */
+ private static final float ALPHA_0 = 0.2f;
+
+ /**
+ * 不透明
+ */
+ private static final float ALPHA_1 = 1f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 300L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.alpha(ALPHA_1);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.alpha(ALPHA_0).setDuration(DURATION);
+ AnimatorProperty animator3 = component.createAnimatorProperty();
+ animator3.alpha(ALPHA_1).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2, animator3, animator2, animator3, animator2, animator1);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/PulseAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/PulseAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..131ac9a6bae33ba97975abfe23fc2b0c58b0c7c8
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/PulseAnimation.java
@@ -0,0 +1,61 @@
+package com.isoftstone.library.impl;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 脉冲效果
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class PulseAnimation implements BaseAnimation {
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_1 = 1f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_2 = 1.2f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 100L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.scaleX(SCALE_1).scaleY(SCALE_1);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.scaleX(SCALE_2).scaleY(SCALE_2).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2, animator1);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/RotateAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/RotateAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2915a3c6325d152fe18c6638aa8c52a1c94873d
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/RotateAnimation.java
@@ -0,0 +1,84 @@
+package com.isoftstone.library.impl;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+
+/**
+ * 按一定角度旋转抖动
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class RotateAnimation implements BaseAnimation {
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_1 = 1f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_2 = 0.9f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_3 = 1.1f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ANGLE_0 = 0f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ANGLE_2 = 2f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 5L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.scaleX(SCALE_1).scaleY(SCALE_1).rotate(ANGLE_0);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.scaleX(SCALE_2).scaleY(SCALE_2).rotate(ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator3 = component.createAnimatorProperty();
+ animator3.scaleX(SCALE_2).scaleY(SCALE_2).rotate(-ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator4 = component.createAnimatorProperty();
+ animator4.scaleX(SCALE_3).scaleY(SCALE_3).rotate(ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator5 = component.createAnimatorProperty();
+ animator5.scaleX(SCALE_3).scaleY(SCALE_3).rotate(-ANGLE_2).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2,
+ animator3, animator4, animator5, animator4, animator5, animator4, animator1);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/RubberBandAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/RubberBandAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..6bc43eb3018f351f02ec3f426840bf53cd432138
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/RubberBandAnimation.java
@@ -0,0 +1,85 @@
+package com.isoftstone.library.impl;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 橡胶
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class RubberBandAnimation implements BaseAnimation {
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_075 = 0.75f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_085 = 0.85f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_1 = 1f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_115 = 1.15f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_125 = 1.25f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_50 = 50L;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_100 = 100L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.scaleX(SCALE_1).scaleY(SCALE_1);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.scaleX(SCALE_125).scaleY(SCALE_075).setDuration(DURATION_100);
+ AnimatorProperty animator3 = component.createAnimatorProperty();
+ animator3.scaleX(SCALE_075).scaleY(SCALE_125).setDuration(DURATION_50);
+ AnimatorProperty animator4 = component.createAnimatorProperty();
+ animator4.scaleX(SCALE_115).scaleY(SCALE_085).setDuration(DURATION_100);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2, animator3, animator4, animator1);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/ShakeAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/ShakeAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..104c096b158bbb4e0b4ecd9d60b1e4b1ad0fd39f
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/ShakeAnimation.java
@@ -0,0 +1,79 @@
+package com.isoftstone.library.impl;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 左右抖动
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class ShakeAnimation implements BaseAnimation {
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 5L;
+
+ /**
+ * 移动距离
+ */
+ private static final float NUM_25 = 25f;
+
+ /**
+ * 移动距离
+ */
+ private static final float NUM_15 = 15f;
+
+ /**
+ * 移动距离
+ */
+ private static final float NUM_6 = 6f;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ float positionX = component.getContentPositionX();
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.moveToX(positionX);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.moveFromX(positionX - NUM_25).moveToX(positionX + NUM_25);
+ AnimatorProperty animator3 = component.createAnimatorProperty();
+ animator3.moveFromX(positionX + NUM_25).moveToX(positionX - NUM_25);
+ AnimatorProperty animator4 = component.createAnimatorProperty();
+ animator4.moveFromX(positionX - NUM_15).moveToX(positionX + NUM_15);
+ AnimatorProperty animator5 = component.createAnimatorProperty();
+ animator5.moveFromX(positionX + NUM_15).moveToX(positionX - NUM_15);
+ AnimatorProperty animator6 = component.createAnimatorProperty();
+ animator6.moveFromX(positionX - NUM_6).moveToX(positionX + NUM_6);
+ AnimatorProperty animator7 = component.createAnimatorProperty();
+ animator7.moveFromX(positionX + NUM_6).moveToX(positionX - NUM_6);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2, animator3,
+ animator2, animator3, animator4, animator5, animator6, animator7, animator6, animator1);
+ animatorGroup.setDuration(DURATION);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/WobbleAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/WobbleAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e1fa48f0aff932466f8f334836ff1d94862895f
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/WobbleAnimation.java
@@ -0,0 +1,88 @@
+package com.isoftstone.library.impl;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 摆动
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class WobbleAnimation implements BaseAnimation {
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 5L;
+
+ /**
+ * 移动距离
+ */
+ private static final float NUM_60 = 60f;
+
+ /**
+ * 移动距离
+ */
+ private static final float NUM_30 = 30f;
+
+ /**
+ * 移动距离
+ */
+ private static final float NUM_6 = 6f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ANGLE_0 = 0f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ANGLE_2 = 3f;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ float positionX = component.getContentPositionX();
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.moveToX(positionX).rotate(ANGLE_0);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.moveFromX(positionX - NUM_60).moveToX(positionX + NUM_60).rotate(ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator3 = component.createAnimatorProperty();
+ animator3.moveFromX(positionX + NUM_60).moveToX(positionX - NUM_60).rotate(-ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator4 = component.createAnimatorProperty();
+ animator4.moveFromX(positionX - NUM_30).moveToX(positionX + NUM_30).rotate(ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator5 = component.createAnimatorProperty();
+ animator5.moveFromX(positionX + NUM_30).moveToX(positionX - NUM_30).rotate(-ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator6 = component.createAnimatorProperty();
+ animator6.moveFromX(positionX - NUM_6).moveToX(positionX + NUM_6).rotate(ANGLE_2).setDuration(DURATION);
+ AnimatorProperty animator7 = component.createAnimatorProperty();
+ animator7.moveFromX(positionX + NUM_6).moveToX(positionX - NUM_6).rotate(-ANGLE_2).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2, animator3, animator2,
+ animator3, animator4, animator5, animator6, animator7, animator6, animator1);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/fade/FadeInAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/fade/FadeInAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed1d27e76eb887c8ff73a22fae4522846e43edf4
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/fade/FadeInAnimation.java
@@ -0,0 +1,66 @@
+package com.isoftstone.library.impl.fade;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 淡入
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class FadeInAnimation implements BaseAnimation {
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 不透明
+ */
+ private static final float ALPHA_1 = 1f;
+
+ /**
+ * 动画时长
+ */
+ private static final long DURATION_0 = 0L;
+
+ /**
+ * 动画时长
+ */
+ private static final long DURATION = 1500L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.alpha(ALPHA_0).setDuration(DURATION_0);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.alpha(ALPHA_1).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/fade/FadeOutAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/fade/FadeOutAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..5fe5cc57b571ec45cf7b8e2c72bc3de60ea49270
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/fade/FadeOutAnimation.java
@@ -0,0 +1,52 @@
+package com.isoftstone.library.impl.fade;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 淡出
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class FadeOutAnimation implements BaseAnimation {
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 1000L;
+
+ /**
+ * 动画属性对象
+ */
+ private AnimatorProperty animatorProperty = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ animatorProperty = component.createAnimatorProperty();
+ animatorProperty.alpha(ALPHA_0).setDuration(DURATION);
+ animatorProperty.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorProperty != null) {
+ animatorProperty.stop();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/roll/RollInAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/roll/RollInAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba42c91040ac24444046ffbee7ceb3408618434e
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/roll/RollInAnimation.java
@@ -0,0 +1,84 @@
+package com.isoftstone.library.impl.roll;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 滚入
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class RollInAnimation implements BaseAnimation {
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 不透明
+ */
+ private static final float ALPHA_1 = 1f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ROTATE_0 = 0f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ROTATE_90 = 90f;
+
+ /**
+ * 除数
+ */
+ private static final float NUM_2 = 2f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_0 = 0L;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 1500L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ float positionX = component.getContentPositionX();
+ int width = component.getWidth();
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.moveByX(positionX - width / NUM_2).rotate(-ROTATE_90).alpha(ALPHA_0).setDuration(DURATION_0);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.moveFromX(positionX - width / NUM_2)
+ .moveToX(positionX).rotate(ROTATE_0).alpha(ALPHA_1).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/roll/RollOutAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/roll/RollOutAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..44f5caa78014379ef9724425a494f47ebaf9eafb
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/roll/RollOutAnimation.java
@@ -0,0 +1,64 @@
+package com.isoftstone.library.impl.roll;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 滚出
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class RollOutAnimation implements BaseAnimation {
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ROTATE_90 = 90f;
+
+ /**
+ * 除数
+ */
+ private static final float NUM_2 = 2f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 1500L;
+
+ /**
+ * 动画属性对象
+ */
+ private AnimatorProperty animator1 = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ float positionX = component.getContentPositionX();
+ int width = component.getWidth();
+ animator1 = component.createAnimatorProperty();
+ animator1.moveFromX(positionX)
+ .moveToX(positionX + width / NUM_2).rotate(ROTATE_90).alpha(ALPHA_0).setDuration(DURATION);
+ animator1.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animator1 != null) {
+ animator1.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/rotate/RotateInAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/rotate/RotateInAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0cbf8ec6c08a9a73da31e64be9eb585cac7d495
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/rotate/RotateInAnimation.java
@@ -0,0 +1,76 @@
+package com.isoftstone.library.impl.rotate;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+ /**
+ * 旋转显示
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class RotateInAnimation implements BaseAnimation {
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 不透明
+ */
+ private static final float ALPHA_1 = 1f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ANGLE_0 = 0f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ANGLE_180 = 180f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_0 = 0L;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_1500 = 1500L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.rotate(-ANGLE_180).alpha(ALPHA_0).setDuration(DURATION_0);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.rotate(ANGLE_0).alpha(ALPHA_1).setDuration(DURATION_1500);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/rotate/RotateOutAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/rotate/RotateOutAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..4681380ffde6e7c1f83ed0385c41650f13b2ca08
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/rotate/RotateOutAnimation.java
@@ -0,0 +1,56 @@
+package com.isoftstone.library.impl.rotate;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 旋转消失
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class RotateOutAnimation implements BaseAnimation {
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 旋转角度
+ */
+ private static final float ANGLE_180 = 180f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_1500 = 1500L;
+
+ /**
+ * 动画属性对象
+ */
+ private AnimatorProperty animator = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ animator = component.createAnimatorProperty();
+ animator.rotate(ANGLE_180).alpha(ALPHA_0).setDuration(DURATION_1500);
+ animator.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animator != null) {
+ animator.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/zoom/ZoomInAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/zoom/ZoomInAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc59f13a4d57e7064b4defd9f7044410d807d739
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/zoom/ZoomInAnimation.java
@@ -0,0 +1,83 @@
+package com.isoftstone.library.impl.zoom;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 小 -> 大显示
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class ZoomInAnimation implements BaseAnimation {
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE = 0.2f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_1 = 1f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_2 = 1.2f;
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 不透明
+ */
+ private static final float ALPHA_1 = 1f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_0 = 0L;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 1500L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.scaleX(SCALE).scaleY(SCALE).alpha(ALPHA_0).setDuration(DURATION_0);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.scaleX(SCALE_2).scaleY(SCALE_2).alpha(ALPHA_1).setDuration(DURATION);
+ AnimatorProperty animator3 = component.createAnimatorProperty();
+ animator3.scaleX(SCALE_1).scaleY(SCALE_1).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2, animator3);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/zoom/ZoomOutAnimation.java b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/zoom/ZoomOutAnimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8cbaa3fe18883ee5937667fef2d438018d5dfb7
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/java/com/isoftstone/library/impl/zoom/ZoomOutAnimation.java
@@ -0,0 +1,71 @@
+package com.isoftstone.library.impl.zoom;
+
+import com.isoftstone.library.BaseAnimation;
+import ohos.agp.animation.AnimatorGroup;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.Component;
+
+/**
+ * 大 -> 小 消失
+ *
+ * @author wjD
+ * @since 2021-02-08
+ */
+public class ZoomOutAnimation implements BaseAnimation {
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE = 0.2f;
+
+ /**
+ * 放大比例
+ */
+ private static final float SCALE_2 = 1.1f;
+
+ /**
+ * 透明
+ */
+ private static final float ALPHA_0 = 0f;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION_0 = 0L;
+
+ /**
+ * 动画执行时长
+ */
+ private static final long DURATION = 1500L;
+
+ /**
+ * 动画组
+ */
+ private AnimatorGroup animatorGroup = null;
+
+ /**
+ * 启动一组动画
+ *
+ * @param component 需要展示动画效果的组件
+ */
+ @Override
+ public void startAnimation(Component component) {
+ AnimatorProperty animator1 = component.createAnimatorProperty();
+ animator1.scaleX(SCALE_2).scaleY(SCALE_2).setDuration(DURATION_0);
+ AnimatorProperty animator2 = component.createAnimatorProperty();
+ animator2.scaleX(SCALE).scaleY(SCALE).alpha(ALPHA_0).setDuration(DURATION);
+ animatorGroup = new AnimatorGroup();
+ animatorGroup.runSerially(animator1, animator2);
+ animatorGroup.start();
+ }
+
+ /**
+ * 停止动画
+ */
+ @Override
+ public void stopAnimation() {
+ if (animatorGroup != null) {
+ animatorGroup.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/resources/base/element/string.json b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e2b219ccdd1183e23968586e5e2e404b41c38c9
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/library/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "library"
+ }
+ ]
+}
diff --git a/015.AndroidViewAnimations_OpenHarmony-master/settings.gradle b/015.AndroidViewAnimations_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..d0c7ee8440156d4a9324ac5357770747425fef57
--- /dev/null
+++ b/015.AndroidViewAnimations_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':library'
diff --git a/016.GifImage_OpenHarmony-master/.gitignore b/016.GifImage_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/016.GifImage_OpenHarmony-master/.idea/.gitignore b/016.GifImage_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/016.GifImage_OpenHarmony-master/.idea/compiler.xml b/016.GifImage_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/gradle.xml b/016.GifImage_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b4380595e4ca36e708ee067aaee08ab6eb13d12b
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/jarRepositories.xml b/016.GifImage_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/misc.xml b/016.GifImage_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1529227879.json b/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1529227879.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1529227879.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1707100846.json b/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1707100846.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-1707100846.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-2047177349.json b/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-2047177349.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_-2047177349.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/previewer/previewConfig.json b/016.GifImage_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..05419abb2d5bfdc57bed27ef6aadbfa27b0d397f
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,13 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "E:\\Matt\\MygifView\\entry": [],
+ "D:\\PCFile\\PCFile\\svn\\019.GifImage\\MygifView\\entry": [
+ "phone"
+ ],
+ "D:\\PCFile\\PCFile\\thirdcomponent\\thirdcomponent\\41.GifImage\\MygifView\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/.idea/vcs.xml b/016.GifImage_OpenHarmony-master/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2bdec2d71b6a5ce4ae49efc37516809c50e4d5e
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/016.GifImage_OpenHarmony-master/016.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204Gif\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/016.GifImage_OpenHarmony-master/016.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204Gif\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..c118c65c29f5045b18b8aac6c70b9915db3292f7
Binary files /dev/null and "b/016.GifImage_OpenHarmony-master/016.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204Gif\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/016.GifImage_OpenHarmony-master/build.gradle b/016.GifImage_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..b83f1bc32d3ed4d4a953fe453ac4ed860f1d4352
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.2.5'
+ classpath 'com.huawei.ohos:decctest:1.0.0.6'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/entry/.gitignore b/016.GifImage_OpenHarmony-master/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/016.GifImage_OpenHarmony-master/entry/build.gradle b/016.GifImage_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..ce742a14a8d40dcc60852e2e639eff5b0ae3e31c
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,15 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ implementation project(":giflibrary")
+ implementation project(":seekbar_harmony")
+}
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/config.json b/016.GifImage_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..c9c85308d18d2735a9df59aca579875602081519
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,72 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.mygifview",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.mygifview",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.READ_USER_STORAGE",
+ "reason": "",
+ "usedScene": {
+ "ability": [
+ "com.isoftstone.mygifview.MainAbility",
+ "com.isoftstone.mygifview.slice.MainAbilitySlice"
+ ],
+ "when": "always"
+ }
+ },
+ {
+ "name": "ohos.permission.READ_MEDIA",
+ "reason": "",
+ "usedScene": {
+ "ability": [
+ "com.isoftstone.mygifview.MainAbility",
+ "com.isoftstone.mygifview.slice.MainAbilitySlice"
+ ],
+ "when": "always"
+ }
+ }
+ ],
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.isoftstone.mygifview.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/MainAbility.java b/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa9ae9310121307fcb3ae1933ea0a14ca02995de
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/MainAbility.java
@@ -0,0 +1,13 @@
+package com.isoftstone.mygifview;
+
+import com.isoftstone.mygifview.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/MyApplication.java b/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..3eb85effef46b16d46b90b0fdc5f540efb2e6077
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/MyApplication.java
@@ -0,0 +1,10 @@
+package com.isoftstone.mygifview;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/slice/MainAbilitySlice.java b/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..acd9b7b3dda82e9af4fa77b5cbbb3d60f6a2784d
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/java/com/isoftstone/mygifview/slice/MainAbilitySlice.java
@@ -0,0 +1,113 @@
+package com.isoftstone.mygifview.slice;
+
+
+import com.example.seekbar_harmony.SeekBarComponent;
+import com.isoftstone.giflibrary.Gif;
+import com.isoftstone.mygifview.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.global.resource.RawFileEntry;
+import ohos.global.resource.ResourceManager;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.io.IOException;
+
+public class MainAbilitySlice extends AbilitySlice {
+ // private GifDecoder gifDecoder;
+ private int index = 1;
+ private RawFileEntry rawFileEntry;
+ private static HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x000110, "GifImage");
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ Gif gifView = (Gif) findComponentById(ResourceTable.Id_testimg);
+ Button pause=(Button) findComponentById(ResourceTable.Id_button_gif_pause);
+ pause.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ gifView.pause();
+ }
+ });
+
+ Button play=(Button)findComponentById(ResourceTable.Id_button_gif_play);
+ play.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ gifView.play();
+ }
+ });
+ ResourceManager resourceManager = getResourceManager();
+ // gifDecoder=new GifDecoder();
+ Button next =(Button)findComponentById(ResourceTable.Id_button_gif_next);
+ next.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ switch (index % 10){
+ case 0:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/deleting.gif");
+ break;
+ case 1:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif1.gif");
+ break;
+ case 2:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif2.gif");
+ break;
+ case 3:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif3.gif");
+ break;
+ case 4:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif4.gif");
+ break;
+ case 5:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif5.gif");
+ break;
+ case 6:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif6.gif");
+ break;
+ case 7:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif7.gif");
+ break;
+ case 8:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif8.gif");
+ break;
+ case 9:
+ rawFileEntry = resourceManager.getRawFileEntry("resources/base/media/gif9.gif");
+ break;
+ }
+ index++;
+ try {
+ gifView.load(rawFileEntry);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ SeekBarComponent seekBar=(SeekBarComponent)findComponentById(ResourceTable.Id_seekbar);
+ seekBar.setOnSeekBarChangeListener(new SeekBarComponent.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(int progress) {
+ gifView.pause();
+ gifView.setSpeed((progress/100f));
+ }
+
+ @Override
+ public void isTouch(boolean isTouch) {
+
+ }
+ });
+ }
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..df7ab90d2445de312550dc6c06f5750f0abd8db4
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,20 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MygifView"
+ },
+ {
+ "name": "bundle",
+ "value": "com.isoftstone.mygifview"
+ },
+ {
+ "name": "application_name",
+ "value": "app"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/color_black_element.xml b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/color_black_element.xml
new file mode 100644
index 0000000000000000000000000000000000000000..77796bd8a5f9183c67b980c8cfcc0128fa13539b
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/color_black_element.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/color_blue_element.xml b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/color_blue_element.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3627114497532cbb929554221254b71612a7161b
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/graphic/color_blue_element.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9533c9ca898c7a687292e779aae7645c46b3ea67
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/.~lock.deleting.gif# b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/.~lock.deleting.gif#
new file mode 100644
index 0000000000000000000000000000000000000000..a7d2103a391aa85e00a31670bb6f82fb75831bb1
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/.~lock.deleting.gif#
@@ -0,0 +1 @@
+,ISOFTSTONE/jhyanq,ISS013001007660,03.02.2021 14:35,file:///C:/Users/jhyanq/AppData/Roaming/LibreOffice/4;
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/coffe.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/coffe.gif
new file mode 100644
index 0000000000000000000000000000000000000000..90417106819b896bbd0859da0b7bdd3117c6827d
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/coffe.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/deleting.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/deleting.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f9a32d37cd271fa764097eb4881170e385ceb5dd
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/deleting.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif1.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif1.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8ff2e8b0ea72346a92f31dfc8358fb28c5db1884
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif1.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif2.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif2.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f81112c33eb64dc335546c4a07782eede840cae0
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif2.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif3.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif3.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b4931be424ffe667f4541bfd98f52e31884928f1
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif3.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif4.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif4.gif
new file mode 100644
index 0000000000000000000000000000000000000000..c452b10a64135becb5786a6bbb824be9a2937b83
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif4.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif5.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif5.gif
new file mode 100644
index 0000000000000000000000000000000000000000..3eee6b37b9822f356bf1537ca12f816e01e29bfa
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif5.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif6.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif6.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8b466f0b3a267f83460a74990fe420e793a702f1
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif6.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif7.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif7.gif
new file mode 100644
index 0000000000000000000000000000000000000000..67851dee439bc94884090d9d2e636863a795b434
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif7.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif8.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif8.gif
new file mode 100644
index 0000000000000000000000000000000000000000..eaefd771f57aaaeb2f4ee31896f89ff75c4e77d3
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif8.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif9.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif9.gif
new file mode 100644
index 0000000000000000000000000000000000000000..34d5ca59d45e20ce284a9e1d9ef0bb55defd49ac
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/gif9.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/next.png b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/next.png
new file mode 100644
index 0000000000000000000000000000000000000000..13dcd23afdbc462877f889ddb191dd662c949ea0
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/next.png differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/pause.png b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c44df0371a419d8d7e06ab524cfaf5ede868860
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/pause.png differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/play.png b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/play.png
new file mode 100644
index 0000000000000000000000000000000000000000..7bb7e4e5ee4e6c08fb92651b5de570bc6650feb6
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/play.png differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/wine.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/wine.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b8eda2858dbc74ed51fdfbc7e2f25e4c9a834a45
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/base/media/wine.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/rawfile/deleting.gif b/016.GifImage_OpenHarmony-master/entry/src/main/resources/rawfile/deleting.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f9a32d37cd271fa764097eb4881170e385ceb5dd
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/rawfile/deleting.gif differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/main/resources/rawfile/icon.png b/016.GifImage_OpenHarmony-master/entry/src/main/resources/rawfile/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/entry/src/main/resources/rawfile/icon.png differ
diff --git a/016.GifImage_OpenHarmony-master/entry/src/test/java/com/isoftstone/mygifview/ExampleTest.java b/016.GifImage_OpenHarmony-master/entry/src/test/java/com/isoftstone/mygifview/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..783214b6386fe1a72600afbd770af6612d6b4065
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/entry/src/test/java/com/isoftstone/mygifview/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.isoftstone.mygifview;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/.gitignore b/016.GifImage_OpenHarmony-master/giflibrary/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/build.gradle b/016.GifImage_OpenHarmony-master/giflibrary/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..de96b90e8ca34fbe5fcbad1f89b24940d21bb09b
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/config.json b/016.GifImage_OpenHarmony-master/giflibrary/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..36bb1cc5b5e4e6f62ee27718c18492f92e21865c
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.mygifview",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.giflibrary",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "giflibrary",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/Gif.java b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/Gif.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0bac3d01d3c84511c7bde1ca5a539fe816b1f08
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/Gif.java
@@ -0,0 +1,204 @@
+package com.isoftstone.giflibrary;
+
+import com.isoftstone.giflibrary.decoder.GifDecoder;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorValue;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Image;
+import ohos.app.Context;
+import ohos.global.resource.*;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Gif extends Image{
+
+ private List pixelMapList=new ArrayList<>();
+
+ private static HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x000110, "GifImage");
+ // 动画
+ private AnimatorValue animatorValue;
+ private ImageSource imageSource;
+ private GifDecoder gifDecoder;
+ private Boolean ispaused=false;
+ private int duration;
+ private float speed=1;
+ public void setSpeed(float speed1) {
+ float EPSINON = (float) 0.00001;
+ if(speed1> EPSINON) {
+ this.speed = speed1;
+ }
+ HiLog.info(label, "speed数据值"+ (speed));
+ animatorValue.stop();
+ animatorValue.setDuration((long) (speed*duration));
+ animatorValue.start();
+ invalidate();
+ }
+ public Gif(Context context) {
+ super(context);
+ }
+
+ public Gif(Context context, AttrSet attrSet) throws IOException, NotExistException, WrongTypeException {
+ super(context, attrSet);
+ gifDecoder=new GifDecoder();
+ ResourceManager resourceManager = context.getResourceManager();
+ ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
+ sourceOptions.formatHint="image/gif";
+
+ if(attrSet.getAttr("image_src").isPresent()) {
+ String id = attrSet.getAttr("image_src").get().getStringValue();
+ Pattern pattern = Pattern.compile("[^0-9]");
+ Matcher matcher = pattern.matcher(id);
+ String all = matcher.replaceAll("");
+ RawFileEntry rawFileEntry = resourceManager.getRawFileEntry(resourceManager.getMediaPath(Integer.parseInt(all)));
+ ImageSource imageSource = ImageSource.create(rawFileEntry.openRawFile(), sourceOptions);
+ gifDecoder.read(rawFileEntry.openRawFile(), (int) rawFileEntry.openRawFileDescriptor().getFileSize());
+
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ } else {
+ invalidate();
+ }
+
+ }
+
+
+ private int i;
+ // 动画侦听函数
+ private final AnimatorValue.ValueUpdateListener mAnimatorUpdateListener
+ = new AnimatorValue.ValueUpdateListener() {
+ @Override
+ public void onUpdate(AnimatorValue animatorValue, float v) {
+ setPixelMap(pixelMapList.get((int)(v*pixelMapList.size())));
+ invalidate();
+ }
+ };
+
+ private void init(ImageSource imageSource) {
+ pixelMapList.clear();
+ duration=0;
+ // invalidate();
+ ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
+ decodingOptions.allowPartialImage=true;
+ i=1;
+ if(gifDecoder.getFrameCount()>0) {
+ while (i < gifDecoder.getFrameCount()) {
+ pixelMapList.add(imageSource.createPixelmap(i, decodingOptions));
+ duration += gifDecoder.getDelay(i);
+ i++;
+ }
+ }else {
+ while (imageSource.createPixelmap(i, decodingOptions)!=null) {
+ pixelMapList.add(imageSource.createPixelmap(i, decodingOptions));
+ duration += gifDecoder.getDelay(i);
+ i++;
+ }
+ }
+ // 启动动画
+ HiLog.info(label, "持续时间"+duration);
+ animatorValue = new AnimatorValue();
+ animatorValue.setCurveType(Animator.CurveType.LINEAR);
+ animatorValue.setDelay(100);
+ animatorValue.setLoopedCount(Animator.INFINITE);
+ animatorValue.setDuration(duration==0 ? 3000:duration);
+ animatorValue.setValueUpdateListener(mAnimatorUpdateListener);
+ animatorValue.start();
+ }
+
+ public void load(InputStream is) {
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(is, sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+ public void load(byte[] data) {
+ gifDecoder.read(data);
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(data, sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+ public void load(ByteBuffer data) {
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(data, sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+ public void load(Callable callable) {
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(callable, sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+ public void load(File file) {
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(file, sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+ public void load(FileDescriptor fd) {
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(fd, sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+ public void load(String pathName) {
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(pathName, sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+
+ public void load(RawFileEntry rawFileEntry) throws IOException {
+ gifDecoder.read(rawFileEntry.openRawFile(), (int) rawFileEntry.openRawFileDescriptor().getFileSize());
+ ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
+ imageSource = ImageSource.create(rawFileEntry.openRawFile(), sourceOption);
+ if (imageSource != null) {
+ init(imageSource);
+ }
+ }
+ public void pause(){
+ if(!ispaused){
+ ispaused=true;
+ }
+ animatorValue.pause();
+ invalidate();
+ }
+ public void play(){
+ if(ispaused){
+ ispaused=false;
+ }
+ animatorValue.start();
+ }
+ public int getDuration(){
+ return duration;
+ }
+ public Boolean isPlaying(){
+ return !ispaused;
+ }
+ public void reset(){
+ animatorValue.stop();
+ animatorValue.start();
+ invalidate();
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifDecoder.java b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifDecoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a2f6485f782a58945c3ba4c6ee049eb4f465f9e
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifDecoder.java
@@ -0,0 +1,921 @@
+/**
+ * Copyright (c) 2013 Xcellent Creations, Inc.
+ * Copyright 2014 Google, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.isoftstone.giflibrary.decoder;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Reads frame data from a GIF image source and decodes it into individual frames
+ * for animation purposes. Image data can be read from either and InputStream source
+ * or a byte[].
+ *
+ * This class is optimized for running animations with the frames, there
+ * are no methods to get individual frame images, only to decode the next frame in the
+ * animation sequence. Instead, it lowers its memory footprint by only housing the minimum
+ * data necessary to decode the next frame in the animation sequence.
+ *
+ * The animation must be manually moved forward using {@link #advance()} before requesting the next
+ * frame. This method must also be called before you request the first frame or an error will
+ * occur.
+ *
+ * Implementation adapted from sample code published in Lyons. (2004). Java for Programmers ,
+ * republished under the MIT Open Source License
+ */
+public class GifDecoder {
+ private static final String TAG = GifDecoder.class.getSimpleName();
+
+ /**
+ * File read status: No errors.
+ */
+ static final int STATUS_OK = 0;
+ /**
+ * File read status: Error decoding file (may be partially decoded).
+ */
+ static final int STATUS_FORMAT_ERROR = 1;
+ /**
+ * File read status: Unable to open source.
+ */
+ static final int STATUS_OPEN_ERROR = 2;
+ /**
+ * Unable to fully decode the current frame.
+ */
+ static final int STATUS_PARTIAL_DECODE = 3;
+ /**
+ * max decoder pixel stack size.
+ */
+ private static final int MAX_STACK_SIZE = 4096;
+
+ /**
+ * GIF Disposal Method meaning take no action.
+ */
+ private static final int DISPOSAL_UNSPECIFIED = 0;
+ /**
+ * GIF Disposal Method meaning leave canvas from previous frame.
+ */
+ private static final int DISPOSAL_NONE = 1;
+ /**
+ * GIF Disposal Method meaning clear canvas to background color.
+ */
+ private static final int DISPOSAL_BACKGROUND = 2;
+ /**
+ * GIF Disposal Method meaning clear canvas to frame before last.
+ */
+ private static final int DISPOSAL_PREVIOUS = 3;
+
+ private static final int NULL_CODE = -1;
+
+ private static final int INITIAL_FRAME_POINTER = -1;
+
+ static final int LOOP_FOREVER = -1;
+
+ private static final int BYTES_PER_INTEGER = 4;
+
+ // Global File Header values and parsing flags.
+ // Active color table.
+ private int[] act;
+ // Private color table that can be modified if needed.
+ private final int[] pct = new int[256];
+
+ // Raw GIF data from input source.
+ private ByteBuffer rawData;
+
+ // Raw data read working array.
+ private byte[] block;
+
+ // Temporary buffer for block reading. Reads 16k chunks from the native buffer for processing,
+ // to greatly reduce JNI overhead.
+ private static final int WORK_BUFFER_SIZE = 16384;
+ private byte[] workBuffer;
+ private int workBufferSize = 0;
+ private int workBufferPosition = 0;
+
+ private GifHeaderParser parser;
+
+ // LZW decoder working arrays.
+ private short[] prefix;
+ private byte[] suffix;
+ private byte[] pixelStack;
+ private byte[] mainPixels;
+ private int[] mainScratch;
+
+ private int framePointer;
+ private int loopIndex;
+ private GifHeader header;
+ private BitmapProvider bitmapProvider;
+ // private Bitmap previousImage;
+ private boolean savePrevious;
+ private int status;
+ private int sampleSize;
+ private int downsampledHeight;
+ private int downsampledWidth;
+ private boolean isFirstFrameTransparent;
+
+ /**
+ * An interface that can be used to provide reused {@link android.graphics.Bitmap}s to avoid GCs
+ * from constantly allocating {@link android.graphics.Bitmap}s for every frame.
+ */
+ interface BitmapProvider {
+ /**
+ * Returns an {@link Bitmap} with exactly the given dimensions and config.
+ *
+ * @param width The width in pixels of the desired {@link android.graphics.Bitmap}.
+ * @param height The height in pixels of the desired {@link android.graphics.Bitmap}.
+ * @param config The {@link android.graphics.Bitmap.Config} of the desired {@link
+ * android.graphics.Bitmap}.
+ */
+ //@NonNull
+ // Bitmap obtain(int width, int height, Bitmap.Config config);
+
+ /**
+ * Releases the given Bitmap back to the pool.
+ */
+ // void release(Bitmap bitmap);
+
+ /**
+ * Returns a byte array used for decoding and generating the frame bitmap.
+ *
+ * @param size the size of the byte array to obtain
+ */
+ byte[] obtainByteArray(int size);
+
+ /**
+ * Releases the given byte array back to the pool.
+ */
+ void release(byte[] bytes);
+
+ /**
+ * Returns an int array used for decoding/generating the frame bitmaps.
+ * @param size
+ */
+ int[] obtainIntArray(int size);
+
+ /**
+ * Release the given array back to the pool.
+ * @param array
+ */
+ void release(int[] array);
+ }
+
+ GifDecoder(BitmapProvider provider, GifHeader gifHeader, ByteBuffer rawData) {
+ this(provider, gifHeader, rawData, 1 /*sampleSize*/);
+ }
+
+ GifDecoder(BitmapProvider provider, GifHeader gifHeader, ByteBuffer rawData,
+ int sampleSize) {
+ this(provider);
+ setData(gifHeader, rawData, sampleSize);
+ }
+//
+ GifDecoder(BitmapProvider provider) {
+ this.bitmapProvider = provider;
+ header = new GifHeader();
+ }
+
+ public GifDecoder() {
+ this(new SimpleBitmapProvider());
+ }
+
+ int getWidth() {
+ return header.width;
+ }
+
+ int getHeight() {
+ return header.height;
+ }
+
+ ByteBuffer getData() {
+ return rawData;
+ }
+
+ /**
+ * Returns the current status of the decoder.
+ *
+ * Status will update per frame to allow the caller to tell whether or not the current frame
+ * was decoded successfully and/or completely. Format and open failures persist across frames.
+ *
+ */
+ int getStatus() {
+ return status;
+ }
+
+ /**
+ * Move the animation frame counter forward.
+ *
+ * @return boolean specifying if animation should continue or if loopCount has been fulfilled.
+ */
+ boolean advance() {
+ if (header.frameCount <= 0) {
+ return false;
+ }
+
+ if(framePointer == getFrameCount() - 1) {
+ loopIndex++;
+ }
+
+ if(header.loopCount != LOOP_FOREVER && loopIndex > header.loopCount) {
+ return false;
+ }
+
+ framePointer = (framePointer + 1) % header.frameCount;
+ return true;
+ }
+
+ /**
+ * Gets display duration for specified frame.
+ *
+ * @param n int index of frame.
+ * @return delay in milliseconds.
+ */
+ public int getDelay(int n) {
+ int delay = -1;
+ if ((n >= 0) && (n < header.frameCount)) {
+ delay = header.frames.get(n).delay;
+ }
+ return delay;
+ }
+
+ /**
+ * Gets display duration for the upcoming frame in ms.
+ */
+ int getNextDelay() {
+ if (header.frameCount <= 0 || framePointer < 0) {
+ return 0;
+ }
+
+ return getDelay(framePointer);
+ }
+
+ /**
+ * Gets the number of frames read from file.
+ *
+ * @return frame count.
+ */
+ public int getFrameCount() {
+ return header.frameCount;
+ }
+
+ /**
+ * Gets the current index of the animation frame, or -1 if animation hasn't not yet started.
+ *
+ * @return frame index.
+ */
+ int getCurrentFrameIndex() {
+ return framePointer;
+ }
+
+ /**
+ * Sets the frame pointer to a specific frame
+ *
+ * @return boolean true if the move was successful
+ */
+ boolean setFrameIndex(int frame) {
+ if(frame < INITIAL_FRAME_POINTER || frame >= getFrameCount()) {
+ return false;
+ }
+ framePointer = frame;
+ return true;
+ }
+
+ /**
+ * Resets the frame pointer to before the 0th frame, as if we'd never used this decoder to
+ * decode any frames.
+ */
+ void resetFrameIndex() {
+ framePointer = INITIAL_FRAME_POINTER;
+ }
+
+ /**
+ * Resets the loop index to the first loop.
+ */
+ void resetLoopIndex() { loopIndex = 0; }
+
+ /**
+ * Gets the "Netscape" iteration count, if any. A count of 0 means repeat indefinitely.
+ *
+ * @return iteration count if one was specified, else 1.
+ */
+ int getLoopCount() { return header.loopCount; }
+
+ /**
+ * Gets the number of loops that have been shown.
+ *
+ * @return iteration count.
+ */
+ int getLoopIndex() {
+ return loopIndex;
+ }
+
+ /**
+ * Returns an estimated byte size for this decoder based on the data provided to {@link
+ * #setData(GifHeader, byte[])}, as well as internal buffers.
+ */
+ int getByteSize() {
+ return rawData.limit() + mainPixels.length + (mainScratch.length * BYTES_PER_INTEGER);
+ }
+
+ /**
+ * Get the next frame in the animation sequence.
+ *
+ * @return Bitmap representation of frame.
+ *//*
+ synchronized Bitmap getNextFrame() {
+ if (header.frameCount <= 0 || framePointer < 0) {
+// if (Log.isLoggable(TAG, Log.DEBUG)) {
+// Log.d(TAG, "unable to decode frame, frameCount=" + header.frameCount + " framePointer="
+// + framePointer);
+// }
+ status = STATUS_FORMAT_ERROR;
+ }
+ if (status == STATUS_FORMAT_ERROR || status == STATUS_OPEN_ERROR) {
+// if (Log.isLoggable(TAG, Log.DEBUG)) {
+// Log.d(TAG, "Unable to decode frame, status=" + status);
+// }
+ return null;
+ }
+ status = STATUS_OK;
+
+ GifFrame currentFrame = header.frames.get(framePointer);
+ GifFrame previousFrame = null;
+ int previousIndex = framePointer - 1;
+ if (previousIndex >= 0) {
+ previousFrame = header.frames.get(previousIndex);
+ }
+
+ // Set the appropriate color table.
+ act = currentFrame.lct != null ? currentFrame.lct : header.gct;
+ if (act == null) {
+// if (Log.isLoggable(TAG, Log.DEBUG)) {
+// Log.d(TAG, "No Valid Color Table for frame #" + framePointer);
+// }
+ // No color table defined.
+ status = STATUS_FORMAT_ERROR;
+ return null;
+ }
+
+ // Reset the transparent pixel in the color table
+ if (currentFrame.transparency) {
+ // Prepare local copy of color table ("pct = act"), see #1068
+ System.arraycopy(act, 0, pct, 0, act.length);
+ // Forget about act reference from shared header object, use copied version
+ act = pct;
+ // Set transparent color if specified.
+ act[currentFrame.transIndex] = 0;
+ }
+
+ // Transfer pixel data to image.
+ return setPixels(currentFrame, previousFrame);
+ }*/
+
+ /**
+ * Reads GIF image from stream.
+ *
+ * @param is containing GIF file.
+ * @return read status code (0 = no errors).
+ */
+ public int read(InputStream is, int contentLength) {
+ if (is != null) {
+ try {
+ int capacity = (contentLength > 0) ? (contentLength + 4096) : 16384;
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream(capacity);
+ int nRead;
+ byte[] data = new byte[16384];
+ while ((nRead = is.read(data, 0, data.length)) != -1) {
+ buffer.write(data, 0, nRead);
+ }
+ buffer.flush();
+
+ read(buffer.toByteArray());
+ } catch (IOException e) {
+ // Log.w(TAG, "Error reading data from stream", e);
+ }
+ } else {
+ status = STATUS_OPEN_ERROR;
+ }
+
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException e) {
+ // Log.w(TAG, "Error closing stream", e);
+ }
+
+ return status;
+ }
+//
+// void clear() {
+// header = null;
+// if (mainPixels != null) {
+// bitmapProvider.release(mainPixels);
+// }
+// if (mainScratch != null) {
+// bitmapProvider.release(mainScratch);
+// }
+// if (previousImage != null) {
+// bitmapProvider.release(previousImage);
+// }
+// previousImage = null;
+// rawData = null;
+// isFirstFrameTransparent = false;
+// if (block != null) {
+// bitmapProvider.release(block);
+// }
+// if (workBuffer != null) {
+// bitmapProvider.release(workBuffer);
+// }
+// }
+
+ synchronized void setData(GifHeader header, byte[] data) {
+ setData(header, ByteBuffer.wrap(data));
+ }
+
+ synchronized void setData(GifHeader header, ByteBuffer buffer) {
+ setData(header, buffer, 1);
+ }
+
+ synchronized void setData(GifHeader header, ByteBuffer buffer, int sampleSize) {
+ if (sampleSize <= 0) {
+ throw new IllegalArgumentException("Sample size must be >=0, not: " + sampleSize);
+ }
+ // Make sure sample size is a power of 2.
+ sampleSize = Integer.highestOneBit(sampleSize);
+ this.status = STATUS_OK;
+ this.header = header;
+ isFirstFrameTransparent = false;
+ framePointer = INITIAL_FRAME_POINTER;
+ resetLoopIndex();
+ // Initialize the raw data buffer.
+ rawData = buffer.asReadOnlyBuffer();
+ rawData.position(0);
+ rawData.order(ByteOrder.LITTLE_ENDIAN);
+
+ // No point in specially saving an old frame if we're never going to use it.
+ savePrevious = false;
+ for (GifFrame frame : header.frames) {
+ if (frame.dispose == DISPOSAL_PREVIOUS) {
+ savePrevious = true;
+ break;
+ }
+ }
+
+ this.sampleSize = sampleSize;
+ downsampledWidth = header.width / sampleSize;
+ downsampledHeight = header.height / sampleSize;
+ // Now that we know the size, init scratch arrays.
+ // TODO Find a way to avoid this entirely or at least downsample it (either should be possible).
+ // mainPixels = bitmapProvider.obtainByteArray(header.width * header.height);
+ // mainScratch = bitmapProvider.obtainIntArray(downsampledWidth * downsampledHeight);
+ }
+
+ private GifHeaderParser getHeaderParser() {
+ if (parser == null) {
+ parser = new GifHeaderParser();
+ }
+ return parser;
+ }
+
+ /**
+ * Reads GIF image from byte array.
+ *
+ * @param data containing GIF file.
+ * @return read status code (0 = no errors).
+ */
+ public synchronized int read(byte[] data) {
+ this.header = getHeaderParser().setData(data).parseHeader();
+ if (data != null) {
+ setData(header, data);
+ }
+
+ return status;
+ }
+
+ /**
+ * Creates new frame image from current data (and previous frames as specified by their
+ * disposition codes).
+ *//*
+ private Bitmap setPixels(GifFrame currentFrame, GifFrame previousFrame) {
+ // Final location of blended pixels.
+ final int[] dest = mainScratch;
+
+ // clear all pixels when meet first frame
+ if (previousFrame == null) {
+ Arrays.fill(dest, 0);
+ }
+
+ // fill in starting image contents based on last image's dispose code
+ if (previousFrame != null && previousFrame.dispose > DISPOSAL_UNSPECIFIED) {
+ // We don't need to do anything for DISPOSAL_NONE, if it has the correct pixels so will our
+ // mainScratch and therefore so will our dest array.
+ if (previousFrame.dispose == DISPOSAL_BACKGROUND) {
+ // Start with a canvas filled with the background color
+ int c = 0;
+ if (!currentFrame.transparency) {
+ c = header.bgColor;
+ if (currentFrame.lct != null && header.bgIndex == currentFrame.transIndex) {
+ c = 0;
+ }
+ } else if (framePointer == 0) {
+ // TODO: We should check and see if all individual pixels are replaced. If they are, the
+ // first frame isn't actually transparent. For now, it's simpler and safer to assume
+ // drawing a transparent background means the GIF contains transparency.
+ isFirstFrameTransparent = true;
+ }
+ fillRect(dest, previousFrame, c);
+ } else if (previousFrame.dispose == DISPOSAL_PREVIOUS) {
+ if (previousImage == null) {
+ fillRect(dest, previousFrame, 0);
+ } else {
+ // Start with the previous frame
+ int downsampledIH = previousFrame.ih / sampleSize;
+ int downsampledIY = previousFrame.iy / sampleSize;
+ int downsampledIW = previousFrame.iw / sampleSize;
+ int downsampledIX = previousFrame.ix / sampleSize;
+ int topLeft = downsampledIY * downsampledWidth + downsampledIX;
+ previousImage.getPixels(dest, topLeft, downsampledWidth,
+ downsampledIX, downsampledIY, downsampledIW, downsampledIH);
+ }
+ }
+ }
+
+ // Decode pixels for this frame into the global pixels[] scratch.
+ decodeBitmapData(currentFrame);
+
+ int downsampledIH = currentFrame.ih / sampleSize;
+ int downsampledIY = currentFrame.iy / sampleSize;
+ int downsampledIW = currentFrame.iw / sampleSize;
+ int downsampledIX = currentFrame.ix / sampleSize;
+ // Copy each source line to the appropriate place in the destination.
+ int pass = 1;
+ int inc = 8;
+ int iline = 0;
+ boolean isFirstFrame = framePointer == 0;
+ for (int i = 0; i < downsampledIH; i++) {
+ int line = i;
+ if (currentFrame.interlace) {
+ if (iline >= downsampledIH) {
+ pass++;
+ switch (pass) {
+ case 2:
+ iline = 4;
+ break;
+ case 3:
+ iline = 2;
+ inc = 4;
+ break;
+ case 4:
+ iline = 1;
+ inc = 2;
+ break;
+ default:
+ break;
+ }
+ }
+ line = iline;
+ iline += inc;
+ }
+ line += downsampledIY;
+ if (line < downsampledHeight) {
+ int k = line * downsampledWidth;
+ // Start of line in dest.
+ int dx = k + downsampledIX;
+ // End of dest line.
+ int dlim = dx + downsampledIW;
+ if (k + downsampledWidth < dlim) {
+ // Past dest edge.
+ dlim = k + downsampledWidth;
+ }
+ // Start of line in source.
+ int sx = i * sampleSize * currentFrame.iw;
+ int maxPositionInSource = sx + ((dlim - dx) * sampleSize);
+ while (dx < dlim) {
+ // Map color and insert in destination.
+ int averageColor;
+ if (sampleSize == 1) {
+ int currentColorIndex = ((int) mainPixels[sx]) & 0x000000ff;
+ averageColor = act[currentColorIndex];
+ } else {
+ // TODO: This is substantially slower (up to 50ms per frame) than just grabbing the
+ // current color index above, even with a sample size of 1.
+ averageColor = averageColorsNear(sx, maxPositionInSource, currentFrame.iw);
+ }
+ if (averageColor != 0) {
+ dest[dx] = averageColor;
+ } else if (!isFirstFrameTransparent && isFirstFrame) {
+ isFirstFrameTransparent = true;
+ }
+ sx += sampleSize;
+ dx++;
+ }
+ }
+ }
+
+ // Copy pixels into previous image
+ if (savePrevious && (currentFrame.dispose == DISPOSAL_UNSPECIFIED
+ || currentFrame.dispose == DISPOSAL_NONE)) {
+ if (previousImage == null) {
+ previousImage = getNextBitmap();
+ }
+ previousImage.setPixels(dest, 0, downsampledWidth, 0, 0, downsampledWidth,
+ downsampledHeight);
+ }
+
+ // Set pixels for current image.
+ Bitmap result = getNextBitmap();
+ result.setPixels(dest, 0, downsampledWidth, 0, 0, downsampledWidth, downsampledHeight);
+ return result;
+ }*/
+
+ private void fillRect(int[] dest, GifFrame frame, int bgColor) {
+ // The area used by the graphic must be restored to the background color.
+ int downsampledIH = frame.ih / sampleSize;
+ int downsampledIY = frame.iy / sampleSize;
+ int downsampledIW = frame.iw / sampleSize;
+ int downsampledIX = frame.ix / sampleSize;
+ int topLeft = downsampledIY * downsampledWidth + downsampledIX;
+ int bottomLeft = topLeft + downsampledIH * downsampledWidth;
+ for (int left = topLeft; left < bottomLeft; left += downsampledWidth) {
+ int right = left + downsampledIW;
+ for (int pointer = left; pointer < right; pointer++) {
+ dest[pointer] = bgColor;
+ }
+ }
+ }
+
+ private int averageColorsNear(int positionInMainPixels, int maxPositionInMainPixels,
+ int currentFrameIw) {
+ int alphaSum = 0;
+ int redSum = 0;
+ int greenSum = 0;
+ int blueSum = 0;
+
+ int totalAdded = 0;
+ // Find the pixels in the current row.
+ for (int i = positionInMainPixels;
+ i < positionInMainPixels + sampleSize && i < mainPixels.length
+ && i < maxPositionInMainPixels; i++) {
+ int currentColorIndex = ((int) mainPixels[i]) & 0xff;
+ int currentColor = act[currentColorIndex];
+ if (currentColor != 0) {
+ alphaSum += currentColor >> 24 & 0x000000ff;
+ redSum += currentColor >> 16 & 0x000000ff;
+ greenSum += currentColor >> 8 & 0x000000ff;
+ blueSum += currentColor & 0x000000ff;
+ totalAdded++;
+ }
+ }
+ // Find the pixels in the next row.
+ for (int i = positionInMainPixels + currentFrameIw;
+ i < positionInMainPixels + currentFrameIw + sampleSize && i < mainPixels.length
+ && i < maxPositionInMainPixels; i++) {
+ int currentColorIndex = ((int) mainPixels[i]) & 0xff;
+ int currentColor = act[currentColorIndex];
+ if (currentColor != 0) {
+ alphaSum += currentColor >> 24 & 0x000000ff;
+ redSum += currentColor >> 16 & 0x000000ff;
+ greenSum += currentColor >> 8 & 0x000000ff;
+ blueSum += currentColor & 0x000000ff;
+ totalAdded++;
+ }
+ }
+ if (totalAdded == 0) {
+ return 0;
+ } else {
+ return ((alphaSum / totalAdded) << 24)
+ | ((redSum / totalAdded) << 16)
+ | ((greenSum / totalAdded) << 8)
+ | (blueSum / totalAdded);
+ }
+ }
+
+ /**
+ * Decodes LZW image data into pixel array. Adapted from John Cristy's BitmapMagick.
+ */
+ private void decodeBitmapData(GifFrame frame) {
+ workBufferSize = 0;
+ workBufferPosition = 0;
+ if (frame != null) {
+ // Jump to the frame start position.
+ rawData.position(frame.bufferFrameStart);
+ }
+
+ int npix = (frame == null) ? header.width * header.height : frame.iw * frame.ih;
+ int available, clear, codeMask, codeSize, endOfInformation, inCode, oldCode, bits, code, count,
+ i, datum,
+ dataSize, first, top, bi, pi;
+
+ if (mainPixels == null || mainPixels.length < npix) {
+ // Allocate new pixel array.
+ // mainPixels = bitmapProvider.obtainByteArray(npix);
+ }
+ if (prefix == null) {
+ prefix = new short[MAX_STACK_SIZE];
+ }
+ if (suffix == null) {
+ suffix = new byte[MAX_STACK_SIZE];
+ }
+ if (pixelStack == null) {
+ pixelStack = new byte[MAX_STACK_SIZE + 1];
+ }
+
+ // Initialize GIF data stream decoder.
+ dataSize = readByte();
+ clear = 1 << dataSize;
+ endOfInformation = clear + 1;
+ available = clear + 2;
+ oldCode = NULL_CODE;
+ codeSize = dataSize + 1;
+ codeMask = (1 << codeSize) - 1;
+ for (code = 0; code < clear; code++) {
+ // XXX ArrayIndexOutOfBoundsException.
+ prefix[code] = 0;
+ suffix[code] = (byte) code;
+ }
+
+ // Decode GIF pixel stream.
+ datum = bits = count = first = top = pi = bi = 0;
+ for (i = 0; i < npix; ) {
+ // Load bytes until there are enough bits for a code.
+ if (count == 0) {
+ // Read a new data block.
+ count = readBlock();
+ if (count <= 0) {
+ status = STATUS_PARTIAL_DECODE;
+ break;
+ }
+ bi = 0;
+ }
+
+ datum += (((int) block[bi]) & 0xff) << bits;
+ bits += 8;
+ bi++;
+ count--;
+
+ while (bits >= codeSize) {
+ // Get the next code.
+ code = datum & codeMask;
+ datum >>= codeSize;
+ bits -= codeSize;
+
+ // Interpret the code.
+ if (code == clear) {
+ // Reset decoder.
+ codeSize = dataSize + 1;
+ codeMask = (1 << codeSize) - 1;
+ available = clear + 2;
+ oldCode = NULL_CODE;
+ continue;
+ }
+
+ if (code > available) {
+ status = STATUS_PARTIAL_DECODE;
+ break;
+ }
+
+ if (code == endOfInformation) {
+ break;
+ }
+
+ if (oldCode == NULL_CODE) {
+ pixelStack[top++] = suffix[code];
+ oldCode = code;
+ first = code;
+ continue;
+ }
+ inCode = code;
+ if (code >= available) {
+ pixelStack[top++] = (byte) first;
+ code = oldCode;
+ }
+ while (code >= clear) {
+ pixelStack[top++] = suffix[code];
+ code = prefix[code];
+ }
+ first = ((int) suffix[code]) & 0xff;
+ pixelStack[top++] = (byte) first;
+
+ // Add a new string to the string table.
+ if (available < MAX_STACK_SIZE) {
+ prefix[available] = (short) oldCode;
+ suffix[available] = (byte) first;
+ available++;
+ if (((available & codeMask) == 0) && (available < MAX_STACK_SIZE)) {
+ codeSize++;
+ codeMask += available;
+ }
+ }
+ oldCode = inCode;
+
+ while (top > 0) {
+ // Pop a pixel off the pixel stack.
+ mainPixels[pi++] = pixelStack[--top];
+ i++;
+ }
+ }
+ }
+
+ // Clear missing pixels.
+ for (i = pi; i < npix; i++) {
+ mainPixels[i] = 0;
+ }
+ }
+
+ /**
+ * Reads the next chunk for the intermediate work buffer.
+ */
+ private void readChunkIfNeeded() {
+ if (workBufferSize > workBufferPosition) {
+ return;
+ }
+ if (workBuffer == null) {
+ workBuffer = bitmapProvider.obtainByteArray(WORK_BUFFER_SIZE);
+ }
+ workBufferPosition = 0;
+ workBufferSize = Math.min(rawData.remaining(), WORK_BUFFER_SIZE);
+ rawData.get(workBuffer, 0, workBufferSize);
+ }
+
+ /**
+ * Reads a single byte from the input stream.
+ */
+ private int readByte() {
+ try {
+ readChunkIfNeeded();
+ return workBuffer[workBufferPosition++] & 0xFF;
+ } catch (Exception e) {
+ status = STATUS_FORMAT_ERROR;
+ return 0;
+ }
+ }
+
+ /**
+ * Reads next variable length block from input.
+ *
+ * @return number of bytes stored in "buffer".
+ */
+ private int readBlock() {
+ int blockSize = readByte();
+ if (blockSize > 0) {
+ try {
+ if (block == null) {
+ block = bitmapProvider.obtainByteArray(255);
+ }
+ final int remaining = workBufferSize - workBufferPosition;
+ if (remaining >= blockSize) {
+ // Block can be read from the current work buffer.
+ System.arraycopy(workBuffer, workBufferPosition, block, 0, blockSize);
+ workBufferPosition += blockSize;
+ } else if (rawData.remaining() + remaining >= blockSize) {
+ // Block can be read in two passes.
+ System.arraycopy(workBuffer, workBufferPosition, block, 0, remaining);
+ workBufferPosition = workBufferSize;
+ readChunkIfNeeded();
+ final int secondHalfRemaining = blockSize - remaining;
+ System.arraycopy(workBuffer, 0, block, remaining, secondHalfRemaining);
+ workBufferPosition += secondHalfRemaining;
+ } else {
+ status = STATUS_FORMAT_ERROR;
+ }
+ } catch (Exception e) {
+ // Log.w(TAG, "Error Reading Block", e);
+ status = STATUS_FORMAT_ERROR;
+ }
+ }
+ return blockSize;
+ }
+
+// private Bitmap getNextBitmap() {
+// Bitmap.Config config = isFirstFrameTransparent
+// ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
+// Bitmap result = bitmapProvider.obtain(downsampledWidth, downsampledHeight, config);
+// setAlpha(result);
+// return result;
+// }
+//
+// @TargetApi(12)
+// private static void setAlpha(Bitmap bitmap) {
+// if (Build.VERSION.SDK_INT >= 12) {
+// bitmap.setHasAlpha(true);
+// }
+// }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifFrame.java b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifFrame.java
new file mode 100644
index 0000000000000000000000000000000000000000..10349bbfc50557d3cdb1f9ce185201aa2b6f0aec
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifFrame.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright 2014 Google, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.isoftstone.giflibrary.decoder;
+
+/**
+ * Inner model class housing metadata for each frame.
+ */
+class GifFrame {
+ int ix, iy, iw, ih;
+ /**
+ * Control Flag.
+ */
+ boolean interlace;
+ /**
+ * Control Flag.
+ */
+ boolean transparency;
+ /**
+ * Disposal Method.
+ */
+ int dispose;
+ /**
+ * Transparency Index.
+ */
+ int transIndex;
+ /**
+ * Delay, in ms, to next frame.
+ */
+ int delay;
+ /**
+ * Index in the raw buffer where we need to start reading to decode.
+ */
+ int bufferFrameStart;
+ /**
+ * Local Color Table.
+ */
+ int[] lct;
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifHeader.java b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifHeader.java
new file mode 100644
index 0000000000000000000000000000000000000000..dabf74885bb1541f3a524bc085d986bd19b95e9f
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifHeader.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright 2014 Google, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.isoftstone.giflibrary.decoder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A header object containing the number of frames in an animated GIF image as well as basic
+ * metadata like width and height that can be used to decode each individual frame of the GIF. Can
+ * be shared by one or more {@link GifDecoder}s to play the same animated GIF in multiple views.
+ */
+public class GifHeader {
+
+ int[] gct = null;
+ int status = GifDecoder.STATUS_OK;
+ int frameCount = 0;
+
+ GifFrame currentFrame;
+ List frames = new ArrayList<>();
+ // Logical screen size.
+ // Full image width.
+ int width;
+ // Full image height.
+ int height;
+
+ // 1 : global color table flag.
+ boolean gctFlag;
+ // 2-4 : color resolution.
+ // 5 : gct sort flag.
+ // 6-8 : gct size.
+ int gctSize;
+ // Background color index.
+ int bgIndex;
+ // Pixel aspect ratio.
+ int pixelAspect;
+ //TODO: this is set both during reading the header and while decoding frames...
+ int bgColor;
+ int loopCount = 0;
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getNumFrames() {
+ return frameCount;
+ }
+
+ /**
+ * Global status code of GIF data parsing.
+ */
+ public int getStatus() {
+ return status;
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifHeaderParser.java b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifHeaderParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ce979f4606d701412d6b4dcfe92db9c342a5f09
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/GifHeaderParser.java
@@ -0,0 +1,424 @@
+/**
+ * Copyright 2014 Google, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.isoftstone.giflibrary.decoder;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/**
+ * A class responsible for creating {@link GifHeader}s from data
+ * representing animated gifs.
+ */
+public class GifHeaderParser {
+ public static final String TAG = "GifHeaderParser";
+
+ // The minimum frame delay in hundredths of a second.
+ static final int MIN_FRAME_DELAY = 2;
+ // The default frame delay in hundredths of a second for GIFs with frame delays less than the
+ // minimum.
+ static final int DEFAULT_FRAME_DELAY = 10;
+
+ private static final int MAX_BLOCK_SIZE = 256;
+ // Raw data read working array.
+ private final byte[] block = new byte[MAX_BLOCK_SIZE];
+
+ private ByteBuffer rawData;
+ private GifHeader header;
+ private int blockSize = 0;
+
+ public GifHeaderParser setData(ByteBuffer data) {
+ reset();
+ rawData = data.asReadOnlyBuffer();
+ rawData.position(0);
+ rawData.order(ByteOrder.LITTLE_ENDIAN);
+ return this;
+ }
+
+ public GifHeaderParser setData(byte[] data) {
+ if (data != null) {
+ setData(ByteBuffer.wrap(data));
+ } else {
+ rawData = null;
+ header.status = GifDecoder.STATUS_OPEN_ERROR;
+ }
+ return this;
+ }
+
+ public void clear() {
+ rawData = null;
+ header = null;
+ }
+
+ private void reset() {
+ rawData = null;
+ Arrays.fill(block, (byte) 0);
+ header = new GifHeader();
+ blockSize = 0;
+ }
+
+ public GifHeader parseHeader() {
+ if (rawData == null) {
+ throw new IllegalStateException("You must call setData() before parseHeader()");
+ }
+ if (err()) {
+ return header;
+ }
+
+ readHeader();
+ if (!err()) {
+ readContents();
+ if (header.frameCount < 0) {
+ header.status = GifDecoder.STATUS_FORMAT_ERROR;
+ }
+ }
+
+ return header;
+ }
+
+ /**
+ * Determines if the GIF is animated by trying to read in the first 2 frames
+ * This method reparses the data even if the header has already been read.
+ */
+ public boolean isAnimated() {
+ readHeader();
+ if (!err()) {
+ readContents(2 /* maxFrames */);
+ }
+ return header.frameCount > 1;
+ }
+
+ /**
+ * Main file parser. Reads GIF content blocks.
+ */
+ private void readContents() {
+ readContents(Integer.MAX_VALUE /* maxFrames */);
+ }
+
+ /**
+ * Main file parser. Reads GIF content blocks. Stops after reading maxFrames
+ */
+ private void readContents(int maxFrames) {
+ // Read GIF file content blocks.
+ boolean done = false;
+ while (!(done || err() || header.frameCount > maxFrames)) {
+ int code = read();
+ switch (code) {
+ // Image separator.
+ case 0x2C:
+ // The graphics control extension is optional, but will always come first if it exists.
+ // If one did
+ // exist, there will be a non-null current frame which we should use. However if one
+ // did not exist,
+ // the current frame will be null and we must create it here. See issue #134.
+ if (header.currentFrame == null) {
+ header.currentFrame = new GifFrame();
+ }
+ readBitmap();
+ break;
+ // Extension.
+ case 0x21:
+ code = read();
+ switch (code) {
+ // Graphics control extension.
+ case 0xf9:
+ // Start a new frame.
+ header.currentFrame = new GifFrame();
+ readGraphicControlExt();
+ break;
+ // Application extension.
+ case 0xff:
+ readBlock();
+ String app = "";
+ for (int i = 0; i < 11; i++) {
+ app += (char) block[i];
+ }
+ if (app.equals("NETSCAPE2.0")) {
+ readNetscapeExt();
+ } else {
+ // Don't care.
+ skip();
+ }
+ break;
+ // Comment extension.
+ case 0xfe:
+ skip();
+ break;
+ // Plain text extension.
+ case 0x01:
+ skip();
+ break;
+ // Uninteresting extension.
+ default:
+ skip();
+ }
+ break;
+ // Terminator.
+ case 0x3b:
+ done = true;
+ break;
+ // Bad byte, but keep going and see what happens break;
+ case 0x00:
+ default:
+ header.status = GifDecoder.STATUS_FORMAT_ERROR;
+ }
+ }
+ }
+
+ /**
+ * Reads Graphics Control Extension values.
+ */
+ private void readGraphicControlExt() {
+ // Block size.
+ read();
+ // Packed fields.
+ int packed = read();
+ // Disposal method.
+ header.currentFrame.dispose = (packed & 0x1c) >> 2;
+ if (header.currentFrame.dispose == 0) {
+ // Elect to keep old image if discretionary.
+ header.currentFrame.dispose = 1;
+ }
+ header.currentFrame.transparency = (packed & 1) != 0;
+ // Delay in milliseconds.
+ int delayInHundredthsOfASecond = readShort();
+ // TODO: consider allowing -1 to indicate show forever.
+ if (delayInHundredthsOfASecond < MIN_FRAME_DELAY) {
+ delayInHundredthsOfASecond = DEFAULT_FRAME_DELAY;
+ }
+ header.currentFrame.delay = delayInHundredthsOfASecond * 10;
+ // Transparent color index
+ header.currentFrame.transIndex = read();
+ // Block terminator
+ read();
+ }
+
+ /**
+ * Reads next frame image.
+ */
+ private void readBitmap() {
+ // (sub)image position & size.
+ header.currentFrame.ix = readShort();
+ header.currentFrame.iy = readShort();
+ header.currentFrame.iw = readShort();
+ header.currentFrame.ih = readShort();
+
+ int packed = read();
+ // 1 - local color table flag interlace
+ boolean lctFlag = (packed & 0x80) != 0;
+ int lctSize = (int) Math.pow(2, (packed & 0x07) + 1);
+ // 3 - sort flag
+ // 4-5 - reserved lctSize = 2 << (packed & 7); // 6-8 - local color
+ // table size
+ header.currentFrame.interlace = (packed & 0x40) != 0;
+ if (lctFlag) {
+ // Read table.
+ header.currentFrame.lct = readColorTable(lctSize);
+ } else {
+ // No local color table.
+ header.currentFrame.lct = null;
+ }
+
+ // Save this as the decoding position pointer.
+ header.currentFrame.bufferFrameStart = rawData.position();
+
+ // False decode pixel data to advance buffer.
+ skipImageData();
+
+ if (err()) {
+ return;
+ }
+
+ header.frameCount++;
+ // Add image to frame.
+ header.frames.add(header.currentFrame);
+ }
+
+ /**
+ * Reads Netscape extension to obtain iteration count.
+ */
+ private void readNetscapeExt() {
+ do {
+ readBlock();
+ if (block[0] == 1) {
+ // Loop count sub-block.
+ int b1 = ((int) block[1]) & 0xff;
+ int b2 = ((int) block[2]) & 0xff;
+ header.loopCount = (b2 << 8) | b1;
+ if(header.loopCount == 0) {
+ header.loopCount = GifDecoder.LOOP_FOREVER;
+ }
+ }
+ } while ((blockSize > 0) && !err());
+ }
+
+
+ /**
+ * Reads GIF file header information.
+ */
+ private void readHeader() {
+ String id = "";
+ for (int i = 0; i < 6; i++) {
+ id += (char) read();
+ }
+ if (!id.startsWith("GIF")) {
+ header.status = GifDecoder.STATUS_FORMAT_ERROR;
+ return;
+ }
+ readLSD();
+ if (header.gctFlag && !err()) {
+ header.gct = readColorTable(header.gctSize);
+ header.bgColor = header.gct[header.bgIndex];
+ }
+ }
+
+ /**
+ * Reads Logical Screen Descriptor.
+ */
+ private void readLSD() {
+ // Logical screen size.
+ header.width = readShort();
+ header.height = readShort();
+ // Packed fields
+ int packed = read();
+ // 1 : global color table flag.
+ header.gctFlag = (packed & 0x80) != 0;
+ // 2-4 : color resolution.
+ // 5 : gct sort flag.
+ // 6-8 : gct size.
+ header.gctSize = 2 << (packed & 7);
+ // Background color index.
+ header.bgIndex = read();
+ // Pixel aspect ratio
+ header.pixelAspect = read();
+ }
+
+ /**
+ * Reads color table as 256 RGB integer values.
+ *
+ * @param ncolors int number of colors to read.
+ * @return int array containing 256 colors (packed ARGB with full alpha).
+ */
+ private int[] readColorTable(int ncolors) {
+ int nbytes = 3 * ncolors;
+ int[] tab = null;
+ byte[] c = new byte[nbytes];
+
+ try {
+ rawData.get(c);
+
+ // TODO: what bounds checks are we avoiding if we know the number of colors?
+ // Max size to avoid bounds checks.
+ tab = new int[MAX_BLOCK_SIZE];
+ int i = 0;
+ int j = 0;
+ while (i < ncolors) {
+ int r = ((int) c[j++]) & 0xff;
+ int g = ((int) c[j++]) & 0xff;
+ int b = ((int) c[j++]) & 0xff;
+ tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
+ }
+ } catch (BufferUnderflowException e) {
+// if (Log.isLoggable(TAG, Log.DEBUG)) {
+// Log.d(TAG, "Format Error Reading Color Table", e);
+// }
+ header.status = GifDecoder.STATUS_FORMAT_ERROR;
+ }
+
+ return tab;
+ }
+
+ /**
+ * Skips LZW image data for a single frame to advance buffer.
+ */
+ private void skipImageData() {
+ // lzwMinCodeSize
+ read();
+ // data sub-blocks
+ skip();
+ }
+
+ /**
+ * Skips variable length blocks up to and including next zero length block.
+ */
+ private void skip() {
+ try {
+ int blockSize;
+ do {
+ blockSize = read();
+ rawData.position(rawData.position() + blockSize);
+ } while (blockSize > 0);
+ } catch (IllegalArgumentException ex) {
+ }
+ }
+
+ /**
+ * Reads next variable length block from input.
+ *
+ * @return number of bytes stored in "buffer"
+ */
+ private int readBlock() {
+ blockSize = read();
+ int n = 0;
+ if (blockSize > 0) {
+ int count = 0;
+ try {
+ while (n < blockSize) {
+ count = blockSize - n;
+ rawData.get(block, n, count);
+
+ n += count;
+ }
+ } catch (Exception e) {
+// if (Log.isLoggable(TAG, Log.DEBUG)) {
+// Log.d(TAG,
+// "Error Reading Block n: " + n + " count: " + count + " blockSize: " + blockSize, e);
+// }
+ header.status = GifDecoder.STATUS_FORMAT_ERROR;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Reads a single byte from the input stream.
+ */
+ private int read() {
+ int curByte = 0;
+ try {
+ curByte = rawData.get() & 0xFF;
+ } catch (Exception e) {
+ header.status = GifDecoder.STATUS_FORMAT_ERROR;
+ }
+ return curByte;
+ }
+
+ /**
+ * Reads next 16-bit value, LSB first.
+ */
+ private int readShort() {
+ // Read 16-bit value.
+ return rawData.getShort();
+ }
+
+ private boolean err() {
+ return header.status != GifDecoder.STATUS_OK;
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/SimpleBitmapProvider.java b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/SimpleBitmapProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3ca44ae813710803d75ff7f5ffb5a272a7002c2
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/java/com/isoftstone/giflibrary/decoder/SimpleBitmapProvider.java
@@ -0,0 +1,27 @@
+package com.isoftstone.giflibrary.decoder;
+
+final class SimpleBitmapProvider implements GifDecoder.BitmapProvider {
+// @Override public Bitmap obtain(int width, int height, Bitmap.Config config) {
+// return Bitmap.createBitmap(width, height, config);
+// }
+//
+// @Override public void release(Bitmap bitmap) {
+// bitmap.recycle();
+// }
+
+ @Override public byte[] obtainByteArray(int size) {
+ return new byte[size];
+ }
+
+ @Override public void release(byte[] bytes) {
+ // no-op
+ }
+
+ @Override public int[] obtainIntArray(int size) {
+ return new int[size];
+ }
+
+ @Override public void release(int[] array) {
+ // no-op
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/giflibrary/src/main/resources/base/element/string.json b/016.GifImage_OpenHarmony-master/giflibrary/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..02ddc2290fabf0726df427ad5e8edbd9b56b093e
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/giflibrary/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "GifLibrary"
+ }
+ ]
+}
diff --git a/016.GifImage_OpenHarmony-master/gradle.properties b/016.GifImage_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/016.GifImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/016.GifImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/016.GifImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/016.GifImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/016.GifImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..19a31aadfdbb8f5862635b65d8c2975647ed99a0
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jan 14 10:14:44 CST 2021
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
diff --git a/016.GifImage_OpenHarmony-master/gradlew b/016.GifImage_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/016.GifImage_OpenHarmony-master/gradlew.bat b/016.GifImage_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/016.GifImage_OpenHarmony-master/seekbar_harmony/.gitignore b/016.GifImage_OpenHarmony-master/seekbar_harmony/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/seekbar_harmony/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/016.GifImage_OpenHarmony-master/seekbar_harmony/build.gradle b/016.GifImage_OpenHarmony-master/seekbar_harmony/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5ea6a3e5c7b67640de4c6f7be770d1e797482cb4
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/seekbar_harmony/build.gradle
@@ -0,0 +1,15 @@
+apply plugin: 'com.huawei.ohos.library'
+//apply from:'../upload.gradle'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/config.json b/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..e0dd0a5b8072fd532f5f8e0d6b61618a4ee8ed09
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.customview",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.seekbar_harmony",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "seekbar_harmony",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/java/com/example/seekbar_harmony/SeekBarComponent.java b/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/java/com/example/seekbar_harmony/SeekBarComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..3754a5324ba8ff24b6d0d698dd5f20eab03675c4
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/java/com/example/seekbar_harmony/SeekBarComponent.java
@@ -0,0 +1,116 @@
+package com.example.seekbar_harmony;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.ProgressBar;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
+import ohos.multimodalinput.event.TouchEvent;
+
+public class SeekBarComponent extends ProgressBar implements Component.DrawTask, Component.TouchEventListener {
+
+ Context mContext;
+ Paint paint;
+ float moveX = 0;
+ int progressValue = 0;
+
+ float moveDistance = 0;
+
+
+ public SeekBarComponent(Context context) {
+ this(context, null);
+ }
+
+ public SeekBarComponent(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public SeekBarComponent(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ mContext = context;
+ setTouchEventListener(this);
+ addDrawTask(this::onDraw);
+ ini();
+
+ }
+
+ private void ini() {
+ paint = new Paint();
+ setMaxValue(100);
+ }
+
+ public void SeekProgress(int progress) {
+ this.progressValue = progress;
+ moveDistance = getWidth() * (progress / 100f);
+// System.out.println("------- getWidth()-------" + getWidth() + "==" + moveDistance);
+ invalidate();
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ int height = component.getHeight();
+ paint.setColor(Color.RED);
+ canvas.drawCircle(moveDistance + 30, height / 2, 30, paint);
+ setProgressValue(progressValue);
+ }
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ changeListener.isTouch(true);
+ int componentWidth = component.getWidth();
+ final boolean pointerUp =
+ touchEvent.getAction() == TouchEvent.OTHER_POINT_UP;
+ final int skipIndex = pointerUp ? touchEvent.getIndex() : -1;
+ float sumX = 0;
+ final int count = touchEvent.getPointerCount();
+ // 把所有还在触摸的手指的位置x,y加起来,后面求平均数,算出中心焦点
+ for (int i = 0; i < count; i++) {
+ if (skipIndex == i) {
+ // 跳过非主要指针的抬起动作
+ continue;
+ }
+ sumX += touchEvent.getPointerPosition(i).getX();
+ }
+ final int div = pointerUp ? count - 1 : count;
+ // 求平均值,算出中心焦点
+ float endUpX = sumX / div - component.getLeft() - 15;
+
+ progressValue = (int) (endUpX / componentWidth * 100);
+ System.out.println("-------progressValue-------" + progressValue);
+
+ switch (touchEvent.getAction()) {
+ case TouchEvent.CANCEL:
+ System.out.println("-------指示事件被中断或取消。。-------");
+ break;
+ case TouchEvent.PRIMARY_POINT_UP:
+ changeListener.isTouch(false);
+ changeListener.onProgressChanged(progressValue);
+ invalidate();
+ break;
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ //表示第一根手指触摸屏幕。
+ moveDistance = moveX = endUpX;
+ break;
+ case TouchEvent.POINT_MOVE:
+ float scrollY = endUpX - moveX;
+ moveDistance += scrollY;
+ moveX = endUpX;
+ invalidate();
+ break;
+ }
+ return true;
+ }
+
+ public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
+ changeListener = listener;
+ }
+
+ OnSeekBarChangeListener changeListener;
+
+ public interface OnSeekBarChangeListener {
+ void onProgressChanged(int progress);
+ void isTouch(boolean isTouch);
+ }
+}
diff --git a/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/resources/base/element/string.json b/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..131623f9f5692e0aa5782723c0d0b7a537d3dec9
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/seekbar_harmony/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "SeekBar_harmony"
+ }
+ ]
+}
diff --git a/016.GifImage_OpenHarmony-master/settings.gradle b/016.GifImage_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..501791ae314f8eda2daa84f22567d61912d70887
--- /dev/null
+++ b/016.GifImage_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':giflibrary',':seekbar_harmony'
diff --git a/017.Pickerview_OpenHarmony-master/.gitignore b/017.Pickerview_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/017.Pickerview_OpenHarmony-master/.idea/.gitignore b/017.Pickerview_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/017.Pickerview_OpenHarmony-master/.idea/compiler.xml b/017.Pickerview_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/.idea/gradle.xml b/017.Pickerview_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f0b6549e50dad37933cc5898dc35391764feb555
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/.idea/jarRepositories.xml b/017.Pickerview_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/.idea/misc.xml b/017.Pickerview_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_422213041.json b/017.Pickerview_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_422213041.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_422213041.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/.idea/previewer/previewConfig.json b/017.Pickerview_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..58e4641e1d6a517e6d9b84b5b118a4a08b85e7f2
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,9 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\PCFile\\PCFile\\svn\\020.Pickerview\\pickerView\\TestMyApplication\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/.idea/vcs.xml b/017.Pickerview_OpenHarmony-master/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2365ab11f9ba6b763735c8fd976420234bb3521
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/017.Pickerview_OpenHarmony-master/017.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204pickerView\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227 .docx" "b/017.Pickerview_OpenHarmony-master/017.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204pickerView\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227 .docx"
new file mode 100644
index 0000000000000000000000000000000000000000..96ef46bfb45fd2753feac0c496e5a41b18fcbcc7
Binary files /dev/null and "b/017.Pickerview_OpenHarmony-master/017.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204pickerView\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227 .docx" differ
diff --git a/017.Pickerview_OpenHarmony-master/build.gradle b/017.Pickerview_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0da9bc913f7350fad9087d8535f200bedce92ed3
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/017.Pickerview_OpenHarmony-master/entry/.gitignore b/017.Pickerview_OpenHarmony-master/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/017.Pickerview_OpenHarmony-master/entry/build.gradle b/017.Pickerview_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..fffe52662e25c3c383023afabb748417ab40eb14
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,20 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/017.Pickerview_OpenHarmony-master/entry/libs/pickerview-release.har b/017.Pickerview_OpenHarmony-master/entry/libs/pickerview-release.har
new file mode 100644
index 0000000000000000000000000000000000000000..702d8f20b1a04986cef16c0083bc6de872b1f7d7
Binary files /dev/null and b/017.Pickerview_OpenHarmony-master/entry/libs/pickerview-release.har differ
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/config.json b/017.Pickerview_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..2ece813e33eee76c02d110cc32094e95d487240a
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,50 @@
+{
+ "app": {
+ "bundleName": "com.isoftstone.testmyapplication",
+ "vendor": "isoftstone",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.isoftstone.testmyapplication",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry",
+ "installationFree": true
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.isoftstone.testmyapplication.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/MainAbility.java b/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..160efb0fa676c4f11d2412640a01636d107002d7
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/MainAbility.java
@@ -0,0 +1,13 @@
+package com.isoftstone.testmyapplication;
+
+import com.isoftstone.testmyapplication.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/MyApplication.java b/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..de726012e10f1c66860aa92b48739ff8f31e376c
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/MyApplication.java
@@ -0,0 +1,10 @@
+package com.isoftstone.testmyapplication;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/slice/MainAbilitySlice.java b/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f1bf569faccc47104b3445a6dc68dbf4fee4cbd
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/main/java/com/isoftstone/testmyapplication/slice/MainAbilitySlice.java
@@ -0,0 +1,269 @@
+package com.isoftstone.testmyapplication.slice;
+
+import com.isoftstone.pickerview.builder.OptionsPickerBuilder;
+import com.isoftstone.pickerview.builder.TimePickerBuilder;
+import com.isoftstone.pickerview.listeners.CustomListener;
+import com.isoftstone.pickerview.listeners.OnOptionsSelectChangeListener;
+import com.isoftstone.pickerview.listeners.OnOptionsSelectListener;
+import com.isoftstone.pickerview.listeners.OnTimeSelectChangeListener;
+import com.isoftstone.pickerview.listeners.OnTimeSelectListener;
+import com.isoftstone.pickerview.view.OptionsPickerView;
+import com.isoftstone.pickerview.view.TimePickerView;
+import com.isoftstone.testmyapplication.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.utils.Color;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+
+public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
+
+ private static final HiLogLabel hiLogLabel = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
+
+ private ArrayList options1Items = new ArrayList<>();
+ private ArrayList> options2Items = new ArrayList<>();
+
+ private Button btn_Options;
+ private Button btn_CustomTime;
+
+ private TimePickerView pvTime, pvCustomTime;
+ private OptionsPickerView pvOptions, pvNoLinkOptions;
+
+ private ArrayList food = new ArrayList<>();
+ private ArrayList clothes = new ArrayList<>();
+ private ArrayList computer = new ArrayList<>();
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ getOptionData();
+
+ initTimePicker();
+ initCustomTimePicker();
+ initOptionPicker();
+ initNoLinkOptionsPicker();
+
+ Button btn_Time = (Button) findComponentById(ResourceTable.Id_btn_Time);
+ btn_Options = (Button) findComponentById(ResourceTable.Id_btn_Options);
+ btn_CustomTime = (Button) findComponentById(ResourceTable.Id_btn_CustomTime);
+ Button btn_no_linkage = (Button) findComponentById(ResourceTable.Id_btn_no_linkage);
+
+
+ btn_Time.setClickedListener(this);
+ btn_Options.setClickedListener(this);
+ btn_CustomTime.setClickedListener(this);
+ btn_no_linkage.setClickedListener(this);
+
+ }
+
+ private void getOptionData() {
+ getNoLinkData();
+
+ //选项1
+ options1Items.add("广东");
+ options1Items.add("湖南");
+ options1Items.add("广西");
+
+ //选项2
+ ArrayList options2Items_01 = new ArrayList<>();
+ options2Items_01.add("广州");
+ options2Items_01.add("佛山");
+ options2Items_01.add("东莞");
+ options2Items_01.add("珠海");
+ ArrayList options2Items_02 = new ArrayList<>();
+ options2Items_02.add("长沙");
+ options2Items_02.add("岳阳");
+ options2Items_02.add("株洲");
+ options2Items_02.add("衡阳");
+ ArrayList options2Items_03 = new ArrayList<>();
+ options2Items_03.add("桂林");
+ options2Items_03.add("玉林");
+ options2Items.add(options2Items_01);
+ options2Items.add(options2Items_02);
+ options2Items.add(options2Items_03);
+ /*--------数据源添加完毕---------*/
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+ @Override
+ public void onClick(Component component) {
+ if (component.getId() == ResourceTable.Id_btn_Time && pvTime != null) {
+ pvTime.show(component);//弹出时间选择器,传递参数过去,回调的时候则可以绑定此view
+ } else if (component.getId() == ResourceTable.Id_btn_Options && pvOptions != null) {
+ pvOptions.show(); //弹出条件选择器
+ } else if (component.getId() == ResourceTable.Id_btn_CustomTime && pvCustomTime != null) {
+ pvCustomTime.show(); //弹出自定义时间选择器
+ } else if (component.getId() == ResourceTable.Id_btn_no_linkage && pvNoLinkOptions != null) {
+ pvNoLinkOptions.show(); //不联动数据选择器
+ }
+ }
+
+ private void getNoLinkData() {
+ food.add("KFC");
+ food.add("MacDonald");
+ food.add("Pizza hut");
+
+ clothes.add("Nike");
+ clothes.add("Adidas");
+ clothes.add("Armani");
+
+ computer.add("ASUS");
+ computer.add("Lenovo");
+ computer.add("Apple");
+ computer.add("HP");
+ }
+
+ private void initTimePicker() {//Dialog 模式下,在底部弹出
+ pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
+ @Override
+ public void onTimeSelect(Date date, Component v) {
+
+ }
+ })
+ .setTimeSelectChangeListener(new OnTimeSelectChangeListener() {
+ @Override
+ public void onTimeSelectChanged(Date date) {
+ HiLog.info(hiLogLabel, "onTimeSelectChanged");
+ }
+ })
+ .setType(new boolean[]{true, true, true, true, true, true})
+ .isDialog(true) //默认设置false ,内部实现将DecorView 作为它的父控件。
+ .addOnCancelClickListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ HiLog.info(hiLogLabel, "onCancelClickListener");
+ }
+
+ })
+ .setItemVisibleCount(5) //若设置偶数,实际值会加1(比如设置6,则最大可见条目为7)
+ .setLineSpacingMultiplier(2.0f)
+ .setContentTextSize(50)
+ .build();
+
+ }
+
+ private void initNoLinkOptionsPicker() {
+ pvNoLinkOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
+
+ @Override
+ public void onOptionsSelect(int options1, int options2, int options3, Component v) {
+
+ String str = "food:" + food.get(options1)
+ + "\nclothes:" + clothes.get(options2)
+ + "\ncomputer:" + computer.get(options3);
+
+ }
+ })
+ .setOptionsSelectChangeListener(new OnOptionsSelectChangeListener() {
+ @Override
+ public void onOptionsSelectChanged(int options1, int options2, int options3) {
+ String str = "options1: " + options1 + "\noptions2: " + options2 + "\noptions3: " + options3;
+ }
+ })
+ .setItemVisibleCount(5)
+ .setSelectOptions(1, 1, 1)
+ .build();
+ pvNoLinkOptions.setNPicker(food, clothes, computer);
+ }
+
+ private void initOptionPicker() {//条件选择器初始化
+
+ /**
+ * 注意 :如果是三级联动的数据(省市区等),请参照 JsonDataActivity 类里面的写法。
+ */
+
+ pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
+ @Override
+ public void onOptionsSelect(int options1, int options2, int options3, Component v) {
+ //返回的分别是三个级别的选中位置
+ String tx = options1Items.get(options1)
+ + options2Items.get(options1).get(options2)
+ /* + options3Items.get(options1).get(options2).get(options3).getPickerViewText()*/;
+ btn_Options.setText(tx);
+ }
+ })
+ .setLineSpacingMultiplier(1.6f)
+ .setTitleText("城市选择")
+ .setContentTextSize(50)//设置滚轮文字大小
+ .setDividerColor(Color.LTGRAY.getValue())//设置分割线的颜色
+ .setSelectOptions(1, 1)//默认选中项
+ .setBgColor(Color.BLACK.getValue())
+ .setTitleColor(Color.LTGRAY.getValue())
+ .setCancelColor(Color.BLUE.getValue())
+ .setSubmitColor(Color.BLUE.getValue())
+ .setTextColorCenter(Color.LTGRAY.getValue())
+ .setOptionsSelectChangeListener(new OnOptionsSelectChangeListener() {
+ @Override
+ public void onOptionsSelectChanged(int options1, int options2, int options3) {
+ }
+ })
+ .build();
+
+ pvOptions.setSelectOptions(1, 1);
+// pvOptions.setPicker(options1Items);//一级选择器
+ pvOptions.setPicker(options1Items, options2Items);//二级选择器
+ /*pvOptions.setPicker(options1Items, options2Items,options3Items);//三级选择器*/
+ }
+
+ private void initCustomTimePicker() {
+ /**
+ * @description
+ *
+ * 注意事项:
+ * 1.自定义布局中,id为 optionspicker 或者 timepicker 的布局以及其子控件必须要有,否则会报空指针.
+ * 具体可参考demo 里面的两个自定义layout布局。
+ * setRangDate方法控制起始终止时间(如果不设置范围,则使用默认时间1900-2100年,此段代码可注释)
+ */
+ Calendar selectedDate = Calendar.getInstance();//系统当前时间
+ Calendar startDate = Calendar.getInstance();
+ startDate.set(2014, 1, 23);
+ Calendar endDate = Calendar.getInstance();
+ endDate.set(2027, 2, 28);
+ //时间选择器 ,自定义布局
+ pvCustomTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
+ @Override
+ public void onTimeSelect(Date date, Component v) {//选中事件回调
+ btn_CustomTime.setText(getTime(date));
+ }
+ })
+ .setDate(selectedDate)
+ .setRangDate(startDate, endDate)
+ .setLayoutRes(new CustomListener() {
+ @Override
+ public void customLayout(Component comp) {
+ }
+ })
+ .setContentTextSize(50)
+ .setTitleSize(50)
+ .setSubCalSize(50)
+ .setType(new boolean[]{true, true, true, true, true, true})
+ .setLineSpacingMultiplier(1.2f)
+ .isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
+ .setDividerColor(0xFF24AD9D)
+ .build();
+ }
+
+ private String getTime(Date date) {//可根据需要自行截取数据显示
+ HiLog.info(hiLogLabel, "choice date millis: " + date.getTime());
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return format.format(date);
+ }
+}
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..984a0f425f4ebcc2b59128a86225fd481b40c558
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "TestMyApplication"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..20264c05005579ce07df5f247c59ac6fbd066e79
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..801448a8bbc52a5901eec43df44f4b78bc2c0390
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/017.Pickerview_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/017.Pickerview_OpenHarmony-master/entry/src/test/java/com/isoftstone/testmyapplication/ExampleTest.java b/017.Pickerview_OpenHarmony-master/entry/src/test/java/com/isoftstone/testmyapplication/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..12d15db0842cc40719a3065b3b1dbf4a978766c2
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/entry/src/test/java/com/isoftstone/testmyapplication/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.isoftstone.testmyapplication;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/017.Pickerview_OpenHarmony-master/gradle.properties b/017.Pickerview_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/017.Pickerview_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/017.Pickerview_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/017.Pickerview_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/017.Pickerview_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/017.Pickerview_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/017.Pickerview_OpenHarmony-master/gradlew b/017.Pickerview_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/017.Pickerview_OpenHarmony-master/gradlew.bat b/017.Pickerview_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/017.Pickerview_OpenHarmony-master/settings.gradle b/017.Pickerview_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07
--- /dev/null
+++ b/017.Pickerview_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry'
diff --git a/018.TableView_OpenHarmony-master/.idea/TableView.iml b/018.TableView_OpenHarmony-master/.idea/TableView.iml
new file mode 100644
index 0000000000000000000000000000000000000000..d6ebd4805981b8400db3e3291c74a743fef9a824
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/.idea/TableView.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/.idea/modules.xml b/018.TableView_OpenHarmony-master/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..88990d11e70b67f704a82e35031491341c0f51f8
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/.idea/vcs.xml b/018.TableView_OpenHarmony-master/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b8635858dc7ad44b93df54b762707ce49eefc
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/.idea/workspace.xml b/018.TableView_OpenHarmony-master/.idea/workspace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1a622da98d4082989016ca85d3a06ca3511524f2
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/.idea/workspace.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1630981265398
+
+
+ 1630981265398
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.gitignore b/018.TableView_OpenHarmony-master/TableView/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/.gitignore b/018.TableView_OpenHarmony-master/TableView/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/compiler.xml b/018.TableView_OpenHarmony-master/TableView/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/gradle.xml b/018.TableView_OpenHarmony-master/TableView/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..92880365c5edf36222421f19a43a85d64a4ded10
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/gradle.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/jarRepositories.xml b/018.TableView_OpenHarmony-master/TableView/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/misc.xml b/018.TableView_OpenHarmony-master/TableView/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-1196855265.json b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-1196855265.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-1196855265.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-304160470.json b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-304160470.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-304160470.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-635855829.json b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-635855829.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_-635855829.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_1761170791.json b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_1761170791.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/phone/phoneSettingConfig_1761170791.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/previewer/previewConfig.json b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..34358839be5b6942e4ce3942689f540e4f8c2b60
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/previewer/previewConfig.json
@@ -0,0 +1,16 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\harmony_third\\harmony\\MyHarmonyApp\\entry": [
+ "phone"
+ ],
+ "D:\\harmony_project\\MyHarmonyApp\\entry": [],
+ "D:\\PCFile\\PCFile\\svn\\021.TableView\\TableView\\entry": [
+ "phone"
+ ],
+ "D:\\PCFile\\PCFile\\svn\\021.TableView\\TableView\\tableview": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/.idea/vcs.xml b/018.TableView_OpenHarmony-master/TableView/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2bdec2d71b6a5ce4ae49efc37516809c50e4d5e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/018.TableView_OpenHarmony-master/TableView/021.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204tableView\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/018.TableView_OpenHarmony-master/TableView/021.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204tableView\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..cec1ea1228791308bb1c2e7d97d5292c51040ce7
Binary files /dev/null and "b/018.TableView_OpenHarmony-master/TableView/021.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204tableView\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/018.TableView_OpenHarmony-master/TableView/build.gradle b/018.TableView_OpenHarmony-master/TableView/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..55ee9133b112de29625c7bbc52be1caad80bdd5f
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/.gitignore b/018.TableView_OpenHarmony-master/TableView/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/build.gradle b/018.TableView_OpenHarmony-master/TableView/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..7488c3c75d38e6cbd22a0e041fb1dc916144543e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ implementation project(path: ':tableview')
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/config.json b/018.TableView_OpenHarmony-master/TableView/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..a0d69306a0a21e62a7eaf1365a47ed6ff68dae9a
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/config.json
@@ -0,0 +1,50 @@
+{
+ "app": {
+ "bundleName": "com.example.myharmonyapp",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.myharmonyapp",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.myharmonyapp.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+
+ ]
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/DataModel.java b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/DataModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e948fa6add96e03d77bd4392522277b692e7668
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/DataModel.java
@@ -0,0 +1,91 @@
+package com.example.myharmonyapp;
+
+import com.test.tableview.IDataModel;
+import com.test.tableview.model.Cell;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * 数据模型
+ *
+ */
+public class DataModel implements IDataModel {
+
+ /**
+ * table表行数
+ */
+ private static final int ROW_SIZE = 165;
+
+ /**
+ * table表列数
+ */
+ private static final int COLUMN_SIZE = 7;
+
+ /**
+ * 获取表内容数据集
+ *
+ * @return 表内容数据集
+ */
+ public List> getCellList() {
+ List> list = new ArrayList<>();
+ for (int i = 0; i < ROW_SIZE; i++) {
+ List cellList = new ArrayList<>();
+ for (int j = 0; j < COLUMN_SIZE; j++) {
+ Object text = "cell " + j + " " + i;
+ final int random = new Random().nextInt();
+ if (j == 0) {
+ text = i;
+ } else if (j == 1) {
+ text = random;
+ }
+
+ // Create dummy id.
+ String id = j + "-" + i;
+
+ Cell cell;
+ String data = String.valueOf(text);
+ if (j == 3) {
+ cell = new Cell(id, data);
+ } else if (j == 4) {
+ cell = new Cell(id, data);
+ } else {
+ cell = new Cell(id, data);
+ }
+ cellList.add(cell);
+ }
+ list.add(cellList);
+ }
+ return list;
+ }
+
+ /**
+ * 获取表头数据集
+ *
+ * @return 表头数据集
+ */
+ public List getColumnHeads() {
+ List cells = new ArrayList<>();
+ for (int i = 0; i < COLUMN_SIZE; i++) {
+ Cell cell = new Cell(String.valueOf(i), "col" + i);
+ cells.add(cell);
+ }
+ return cells;
+ }
+
+ /**
+ * 获取每行第一列数据集
+ *
+ * @return 每行第一列数据集
+ */
+ public List getRowHeads() {
+ List cells = new ArrayList<>();
+ for (int i = 0; i < ROW_SIZE; i++) {
+ Cell cell = new Cell(String.valueOf(i), "row" + i);
+ cells.add(cell);
+ }
+ return cells;
+ }
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/MainAbility.java b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..e85692d8a47c3822cdbdb9cc76e964022faf744e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/MainAbility.java
@@ -0,0 +1,19 @@
+package com.example.myharmonyapp;
+
+import com.example.myharmonyapp.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+/**
+ * 程序入口
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/MyApplication.java b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1b37c3aa35b2a7eb453fd900a7e3b21c729bb3d
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/MyApplication.java
@@ -0,0 +1,16 @@
+package com.example.myharmonyapp;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * MyApplication
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/slice/MainAbilitySlice.java b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..08530ed0762ad7e3b3ef3fdc2af67aaf2352828a
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/java/com/example/myharmonyapp/slice/MainAbilitySlice.java
@@ -0,0 +1,277 @@
+package com.example.myharmonyapp.slice;
+
+import com.test.tableview.ContainerModel;
+import com.example.myharmonyapp.DataModel;
+import com.example.myharmonyapp.ResourceTable;
+import com.test.tableview.TableView;
+import com.test.tableview.listener.filter.FilterListener;
+import com.test.tableview.listener.itemclick.TableItemClickListeners;
+import com.test.tableview.pagination.Pagination;
+import com.test.tableview.scroll.ScrollUtils;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.NestedScrollView;
+import ohos.agp.components.Text;
+import ohos.agp.components.TextField;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+/**
+ * 主线程
+ *
+ */
+public class MainAbilitySlice extends AbilitySlice {
+
+ /**
+ * 按钮上一页
+ */
+ private Button previousButton;
+
+ /**
+ * 按钮下一页
+ */
+ private Button nextButton;
+
+ /**
+ * 页数输入框
+ */
+ private TextField pageNumberField;
+
+ /**
+ * 按钮:到指定页数
+ */
+ private Button goPageButton;
+
+ /**
+ * 是否分页
+ */
+ private boolean paginationEnabled = true;
+
+ /**
+ * 分页详情信息描述
+ */
+ private Text tablePaginationDetails;
+
+ /**
+ * 分页
+ */
+ private Pagination pagination;
+
+ /**
+ * 列头视图模型
+ */
+ private ListContainer columnHeadContainer;
+
+ /**
+ * 行头视图模型
+ */
+ private ListContainer rowHeadContainer;
+
+ /**
+ * 单元格视图模型
+ */
+ private ListContainer cellContainer;
+
+ /**
+ * 滚动组件
+ */
+ private NestedScrollView colHeadScroll;
+
+ /**
+ * 滚动组件
+ */
+ private NestedScrollView rowHeadScroll;
+
+ /**
+ * 滚动组件
+ */
+ private NestedScrollView cellsScroll;
+
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ TextField textField = (TextField) findComponentById(ResourceTable.Id_search_field);
+ Button filterButton = (Button) findComponentById(ResourceTable.Id_search_button);
+
+ previousButton = (Button) findComponentById(ResourceTable.Id_previous_button);
+ nextButton = (Button) findComponentById(ResourceTable.Id_next_button);
+ pageNumberField = (TextField) findComponentById(ResourceTable.Id_go_page_number);
+
+ goPageButton = (Button) findComponentById(ResourceTable.Id_goPage_button);
+ tablePaginationDetails = (Text) findComponentById(ResourceTable.Id_pagination_details);
+
+ DirectionalLayout goPageLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_go_page_layout);
+
+ DirectionalLayout paginationLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_pagination_layout);
+
+ colHeadScroll = (NestedScrollView) findComponentById(ResourceTable.Id_col_head_scroll);
+ rowHeadScroll = (NestedScrollView) findComponentById(ResourceTable.Id_row_head_scroll);
+ cellsScroll = (NestedScrollView) findComponentById(ResourceTable.Id_cells_scroll);
+
+
+ columnHeadContainer = (ListContainer) findComponentById(ResourceTable.Id_column_head_container);
+ rowHeadContainer = (ListContainer) findComponentById(ResourceTable.Id_row_head_container);
+ cellContainer = (ListContainer) findComponentById(ResourceTable.Id_cells_container);
+ DataModel dataModel = new DataModel();
+ ContainerModel containerModel = new ContainerModel(columnHeadContainer, rowHeadContainer, cellContainer);
+
+ TableView tableView = new TableView(this, dataModel, containerModel);
+
+ initTableView(tableView);
+
+ previousButton.setVisibility(Component.HIDE);
+ if (paginationEnabled) {
+ paginationLayout.setVisibility(Component.VISIBLE);
+ goPageLayout.setVisibility(Component.VISIBLE);
+
+ previousButton.setClickedListener(clickListener);
+
+ nextButton.setClickedListener(clickListener);
+
+ goPageButton.setClickedListener(clickListener);
+ } else {
+ paginationLayout.setVisibility(Component.HIDE);
+ goPageLayout.setVisibility(Component.HIDE);
+ }
+
+ // 之前写法有问题,这样子写导致拿不到输入框里面的数据
+ //FilterListener filterListener = new FilterListener(tableView, textField.getText());
+ //filterButton.setClickedListener(filterListener.getFilter());
+ filterButton.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ HiLogLabel hiLogLabel = new HiLogLabel(3, 0xdf, "filter");
+ HiLog.info(hiLogLabel,textField.getText());
+ FilterListener filterListener = new FilterListener(tableView, textField.getText());
+ filterListener.initFilter();
+ }
+ });
+ if (paginationEnabled) {
+ pagination = new Pagination(tableView, this);
+ pagination.setTableViewPageTurnedListener(onTableViewPageTurnedListener);
+ }
+
+ }
+
+ /**
+ * 初始化table
+ *
+ * @param tableView tableView对象
+ */
+ private void initTableView(TableView tableView) {
+ TableItemClickListeners tableListener = new TableItemClickListeners(tableView, getContext());
+ rowHeadContainer.setItemClickedListener(tableListener.getRowHeadClickListener());
+ columnHeadContainer.setItemClickedListener(tableListener.getColumnHeadClickListener());
+ cellContainer.setClickedListener(tableListener.getCellClickListener());
+
+ rowHeadContainer.setItemProvider(tableView.getRowHeaderRecyclerAdapter());
+ columnHeadContainer.setItemProvider(tableView.getColumnHeaderRecyclerAdapter());
+
+ cellContainer.setItemProvider(tableView.getCellRecyclerViewAdapter());
+
+ // 设置同步滑动
+ ScrollUtils scrollUtils = new ScrollUtils(colHeadScroll, rowHeadScroll, cellsScroll);
+ scrollUtils.scroll();
+
+ }
+
+ /**
+ * 分页监听事件
+ */
+ private final Pagination.OnTableViewPageTurnedListener onTableViewPageTurnedListener =
+ new Pagination.OnTableViewPageTurnedListener() {
+ @Override
+ public void onPageTurned(int numItems, int itemsStart, int itemsEnd) {
+ int currentPage = pagination.getCurrentPage();
+ int pageCount = pagination.getPageCount();
+ previousButton.setVisibility(Component.VISIBLE);
+ nextButton.setVisibility(Component.VISIBLE);
+
+ if (currentPage == 1 && pageCount == 1) {
+ previousButton.setVisibility(Component.HIDE);
+ nextButton.setVisibility(Component.HIDE);
+ }
+
+ if (currentPage == 1) {
+ previousButton.setVisibility(Component.HIDE);
+ }
+
+ if (currentPage == pageCount) {
+ nextButton.setVisibility(Component.HIDE);
+ }
+
+ tablePaginationDetails.setText("Page " + currentPage + " , showing items " + itemsStart + " - " + itemsEnd);
+ }
+ };
+
+ /**
+ * 点击事件监听
+ */
+ private final Component.ClickedListener clickListener = new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ if (component == previousButton) {
+ previousTablePage();
+ } else if (component == nextButton) {
+ nextTablePage();
+ } else if (component == goPageButton) {
+ String pageText = pageNumberField.getText().trim();
+ if ("".equals(pageText)) {
+ goToTablePage(1);
+ } else {
+ if (!pageText.matches("^[0-9]+$")) {
+ return;
+ }
+ goToTablePage(Integer.parseInt(pageText));
+ }
+ }
+ }
+ };
+
+ /**
+ * 跳转下一页
+ */
+ private void nextTablePage() {
+ if (pagination != null) {
+ pagination.nextPage();
+ }
+ }
+
+ /**
+ * 跳转上一页
+ */
+ private void previousTablePage() {
+ if (pagination != null) {
+ pagination.previousPage();
+ }
+ }
+
+ /**
+ * 跳转指定页数
+ *
+ * @param page 指定页数
+ */
+ private void goToTablePage(int page) {
+ if (pagination != null) {
+ pagination.goToPage(page);
+ }
+ }
+
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/element/string.json b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..7d0c117a879dbe1aff378005bc1542d02701c140
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,36 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyHarmonyApp"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "mainability2_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "mainability3_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "button_text_size",
+ "value": "12fp"
+ },
+ {
+ "name": "button_text_color",
+ "value": "white"
+ },
+ {
+ "name": "list_view_width",
+ "value": "3000vp"
+ },
+ {
+ "name": "list_view_height",
+ "value": "3000vp"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/background_ability_main.xml b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4408427bb6a4e04a4aecf6622b9664b8af47d12
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/capsule_button_element.xml b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/capsule_button_element.xml
new file mode 100644
index 0000000000000000000000000000000000000000..91334020975c2048e8ee1ec6ca6f5ed357584d7f
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/capsule_button_element.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/oval_button.xml b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/oval_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..971179d1d4191a5e3269bbb321018d16576b9e4b
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/graphic/oval_button.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/layout/ability_main.xml b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1259c83f09d8366012b772ba1fbcf548896b045c
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/media/icon.png b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/018.TableView_OpenHarmony-master/TableView/entry/src/main/resources/base/media/icon.png differ
diff --git a/018.TableView_OpenHarmony-master/TableView/entry/src/test/java/com/example/myharmonyapp/ExampleTest.java b/018.TableView_OpenHarmony-master/TableView/entry/src/test/java/com/example/myharmonyapp/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3bd186db173ff58c8cba79da70edf158001d35da
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/entry/src/test/java/com/example/myharmonyapp/ExampleTest.java
@@ -0,0 +1,19 @@
+package com.example.myharmonyapp;
+
+import org.junit.Test;
+
+/**
+ * 测试类
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class ExampleTest {
+
+ /**
+ * 测试方法
+ */
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/gradle.properties b/018.TableView_OpenHarmony-master/TableView/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/018.TableView_OpenHarmony-master/TableView/gradle/wrapper/gradle-wrapper.jar b/018.TableView_OpenHarmony-master/TableView/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/018.TableView_OpenHarmony-master/TableView/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/018.TableView_OpenHarmony-master/TableView/gradle/wrapper/gradle-wrapper.properties b/018.TableView_OpenHarmony-master/TableView/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/018.TableView_OpenHarmony-master/TableView/gradlew b/018.TableView_OpenHarmony-master/TableView/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/018.TableView_OpenHarmony-master/TableView/gradlew.bat b/018.TableView_OpenHarmony-master/TableView/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/018.TableView_OpenHarmony-master/TableView/settings.gradle b/018.TableView_OpenHarmony-master/TableView/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..547868f02d568155eb2a14f2696ccda01f4110a2
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':tableview', ':testtableview'
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/.gitignore b/018.TableView_OpenHarmony-master/TableView/tableview/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/build.gradle b/018.TableView_OpenHarmony-master/TableView/tableview/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..de96b90e8ca34fbe5fcbad1f89b24940d21bb09b
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/config.json b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..4e816fc13fa1955859b13bbfa80c39e5813f364a
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.myharmonyapp",
+ "vendor": "test",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.test.tableview",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "tableview",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/ContainerModel.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/ContainerModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..c691b99118b1447c7d2f197d625f4eb3d5e7608c
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/ContainerModel.java
@@ -0,0 +1,51 @@
+package com.test.tableview;
+
+import ohos.agp.components.ListContainer;
+
+/**
+ * 表视图模型
+ *
+ */
+public class ContainerModel {
+
+ /**
+ * 列头视图模型
+ */
+ private ListContainer columnHeadContainer;
+
+ /**
+ * 行头视图模型
+ */
+ private ListContainer rowHeadContainer;
+
+ /**
+ * 单元格视图模型
+ */
+ private ListContainer cellContainer;
+
+ /**
+ * 构造函数
+ *
+ * @param columnHeadContainer 列头视图模型
+ * @param rowHeadContainer 行头视图模型
+ * @param cellContainer 单元格视图模型
+ */
+ public ContainerModel(ListContainer columnHeadContainer, ListContainer rowHeadContainer, ListContainer cellContainer) {
+ this.columnHeadContainer = columnHeadContainer;
+ this.rowHeadContainer = rowHeadContainer;
+ this.cellContainer = cellContainer;
+ }
+
+ public ListContainer getColumnHeadContainer() {
+ return columnHeadContainer;
+ }
+
+ public ListContainer getRowHeadContainer() {
+ return rowHeadContainer;
+ }
+
+ public ListContainer getCellContainer() {
+ return cellContainer;
+ }
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/IDataModel.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/IDataModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1965dce5cce6b18dcbff95a5b7387a06665cf2c
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/IDataModel.java
@@ -0,0 +1,34 @@
+package com.test.tableview;
+
+import com.test.tableview.model.Cell;
+
+import java.util.List;
+
+/**
+ * 数据模型接口
+ *
+ */
+public interface IDataModel {
+
+ /**
+ * 获取表内容数据集
+ *
+ * @return 表内容数据集
+ */
+ List> getCellList();
+
+ /**
+ * 获取表头数据集
+ *
+ * @return 表头数据集
+ */
+ List getColumnHeads();
+
+ /**
+ * 获取每行第一列数据集
+ *
+ * @return 每行第一列数据集
+ */
+ List getRowHeads();
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/TableView.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/TableView.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff835296cc089b8af6ad61e9e174014e7990e555
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/TableView.java
@@ -0,0 +1,134 @@
+package com.test.tableview;
+
+import com.test.tableview.adapter.CellRecyclerViewAdapter;
+import com.test.tableview.adapter.ColumnHeaderRecyclerAdapter;
+import com.test.tableview.adapter.RowHeaderRecyclerAdapter;
+import com.test.tableview.layoutmanager.FitWidthUtils;
+import com.test.tableview.model.Cell;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.util.List;
+
+/**
+ * 表视图模型
+ *
+ */
+public class TableView {
+
+ /**
+ * 视图模型
+ */
+ private ContainerModel containerModel;
+ /**
+ * 单元格数据适配器
+ */
+ private CellRecyclerViewAdapter cellRecyclerViewAdapter;
+ /**
+ * table表列头数据适配器
+ */
+ private ColumnHeaderRecyclerAdapter columnHeaderRecyclerAdapter;
+ /**
+ * table表行头数据适配器
+ */
+ private RowHeaderRecyclerAdapter rowHeaderRecyclerAdapter;
+
+ /**
+ * 上下文对象
+ */
+ private Context context;
+
+ /**
+ * 数据模型
+ */
+ private IDataModel dataModel;
+
+ /**
+ * 构造器
+ *
+ * @param context 上下文内容对象
+ * @param dataModel 表数据模型
+ * @param containerModel list模型
+ */
+ public TableView(Context context, IDataModel dataModel, ContainerModel containerModel) {
+ this.context = context;
+ this.dataModel = dataModel;
+ this.containerModel = containerModel;
+ initTableView(dataModel);
+ }
+
+ /**
+ * 初始化表数据
+ *
+ * @param dataModel 数据模型
+ */
+ private void initTableView(IDataModel dataModel) {
+ initView(dataModel);
+ }
+
+ /**
+ * 初始化表数据
+ *
+ * @param dataModel 数据模型
+ */
+ public void initView(IDataModel dataModel) {
+
+ List colHeads = dataModel.getColumnHeads();
+
+ List> cells = dataModel.getCellList();
+
+ // 设置列自适应宽度
+ List widthSize = FitWidthUtils.fitColWidthSize(colHeads, cells);
+ HiLogLabel hiLogLabel = new HiLogLabel(3, 0xdf, "initView");
+ HiLog.info(hiLogLabel, widthSize.toString());
+
+ for (int index = 0; index < colHeads.size(); index++) {
+ Cell colHeadCell = colHeads.get(index);
+ colHeadCell.setWidth(widthSize.get(index));
+ }
+
+ for (List cellList : cells) {
+ for (int index = 0; index < cellList.size(); index++) {
+ Cell cell = cellList.get(index);
+ cell.setWidth(widthSize.get(index));
+ }
+ }
+
+ // 設置rowhead
+ rowHeaderRecyclerAdapter = new RowHeaderRecyclerAdapter(dataModel.getRowHeads(), context);
+
+ columnHeaderRecyclerAdapter = new ColumnHeaderRecyclerAdapter(colHeads, context);
+
+ cellRecyclerViewAdapter = new CellRecyclerViewAdapter(cells, context);
+ }
+
+ public CellRecyclerViewAdapter getCellRecyclerViewAdapter() {
+ return cellRecyclerViewAdapter;
+ }
+
+
+ public ColumnHeaderRecyclerAdapter getColumnHeaderRecyclerAdapter() {
+ return columnHeaderRecyclerAdapter;
+ }
+
+
+ public RowHeaderRecyclerAdapter getRowHeaderRecyclerAdapter() {
+ return rowHeaderRecyclerAdapter;
+ }
+
+
+ public Context getContext() {
+ return context;
+ }
+
+
+ public IDataModel getDataModel() {
+ return dataModel;
+ }
+
+
+ public ContainerModel getContainerModel() {
+ return containerModel;
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/CellRecyclerViewAdapter.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/CellRecyclerViewAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..779e7720e9a9d3f7119d160c92fab11c76b4efa3
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/CellRecyclerViewAdapter.java
@@ -0,0 +1,96 @@
+package com.test.tableview.adapter;
+
+import com.test.tableview.ResourceTable;
+import com.test.tableview.model.Cell;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.RecycleItemProvider;
+import ohos.app.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 单元格数据适配器
+ *
+ */
+public class CellRecyclerViewAdapter extends RecycleItemProvider {
+
+ /**
+ * 数据集合
+ */
+ private List> dataItems;
+
+ /**
+ * 上下文对象
+ */
+ private Context context;
+
+ /**
+ * 构造函数
+ *
+ * @param dataItems 单元格数据集
+ * @param context 上下文内容对象
+ */
+ public CellRecyclerViewAdapter(List> dataItems, Context context) {
+ this.dataItems = dataItems;
+ this.context = context;
+ }
+
+ /**
+ * 设置单元格数据
+ *
+ * @param itemList 单元格数据集
+ * @param notifyDataSet 是否刷新数据
+ */
+ public void setItems(List> itemList, boolean notifyDataSet) {
+ dataItems = new ArrayList<>(itemList);
+ if (notifyDataSet) {
+ this.notifyDataChanged();
+ }
+ }
+
+
+ public List> getItems() {
+ return dataItems;
+ }
+
+ @Override
+ public int getCount() {
+ return dataItems.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return dataItems.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+ if (position >= dataItems.size()) {
+ return null;
+ }
+ Component component = convertComponent;
+ if (component == null) {
+ component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_cell_row, null, false);
+ }
+ ListContainer listContainer = (ListContainer) component.findComponentById(ResourceTable.Id_cell_row_container);
+ List cells = dataItems.get(position);
+ CellRowRecyclerViewAdapter cellRowRecyclerViewAdapter = new CellRowRecyclerViewAdapter(cells, context);
+ listContainer.setItemProvider(cellRowRecyclerViewAdapter);
+ return component;
+ }
+
+ @Override
+ public int getComponentTypeCount() {
+ return 3;
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/CellRowRecyclerViewAdapter.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/CellRowRecyclerViewAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfa702eb99de19d1955ef430c901ad978f8b693e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/CellRowRecyclerViewAdapter.java
@@ -0,0 +1,82 @@
+package com.test.tableview.adapter;
+
+import com.test.tableview.ResourceTable;
+import com.test.tableview.model.Cell;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.RecycleItemProvider;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.ShapeElement;
+import ohos.agp.window.dialog.ToastDialog;
+import ohos.app.Context;
+
+import java.util.List;
+
+/**
+ * 表格每行数据适配器
+ *
+ */
+public class CellRowRecyclerViewAdapter extends RecycleItemProvider {
+ /**
+ * 上下文对象
+ */
+ private Context context;
+
+ /**
+ * 数据集合
+ */
+ private List cellList;
+
+ /**
+ * 构造函数
+ *
+ * @param cellList 单元格数据集
+ * @param context 上下文内容对象
+ */
+ public CellRowRecyclerViewAdapter(List cellList, Context context) {
+ this.context = context;
+ this.cellList = cellList;
+ }
+
+ @Override
+ public int getCount() {
+ return cellList.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return cellList.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+ Component component = convertComponent;
+ if (component == null) {
+ component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_cell_item, null, false);
+ }
+ Text text = (Text) component.findComponentById(ResourceTable.Id_cell_item);
+ Cell cell = cellList.get(position);
+ text.setText(cell.getData());
+ ShapeElement shapeElement = new ShapeElement();
+ shapeElement.setRgbColor(cell.getRgbColor());
+ text.setBackground(shapeElement);
+ if (cell.getWidth() != 0) {
+ text.setWidth(cell.getWidth());
+ }
+
+ component.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ new ToastDialog(context).setText(text.getText() + " is been clicked").show();
+ }
+ });
+ return component;
+ }
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/ColumnHeaderRecyclerAdapter.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/ColumnHeaderRecyclerAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ec33603608bd7d96ffd2a99678edfe9d41c36ad
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/ColumnHeaderRecyclerAdapter.java
@@ -0,0 +1,96 @@
+package com.test.tableview.adapter;
+
+import com.test.tableview.ResourceTable;
+import com.test.tableview.model.Cell;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.RecycleItemProvider;
+import ohos.agp.components.Text;
+import ohos.agp.components.TextFilter;
+import ohos.agp.components.element.ShapeElement;
+import ohos.app.Context;
+
+import java.util.List;
+
+/**
+ * 表格列头数据适配器
+ *
+ */
+public class ColumnHeaderRecyclerAdapter extends RecycleItemProvider {
+
+ /**
+ * 数据集合
+ */
+ private List cells;
+
+ /**
+ * 上下文对象
+ */
+ private Context context;
+
+ /**
+ * 构造函数
+ *
+ * @param cells 单元格数据集
+ * @param context 上下文内容对象
+ */
+ public ColumnHeaderRecyclerAdapter(List cells, Context context) {
+ this.cells = cells;
+ this.context = context;
+ }
+
+ public List getItems() {
+ return cells;
+ }
+
+ @Override
+ public int getCount() {
+ return cells.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return cells.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+ Component component = convertComponent;
+ if (component == null) {
+ component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_cell_item, null, false);
+ }
+ Cell cell = cells.get(position);
+ Text text = (Text) component.findComponentById(ResourceTable.Id_cell_item);
+ text.setText(cell.getData());
+ ShapeElement shapeElement = new ShapeElement();
+ shapeElement.setRgbColor(cell.getRgbColor());
+ text.setBackground(shapeElement);
+ if (cell.getWidth() != 0) {
+ text.setWidth(cell.getWidth());
+ }
+ return component;
+ }
+
+ @Override
+ public int getComponentTypeCount() {
+ return 1;
+ }
+
+ @Override
+ public void setFilter(TextFilter filter) {
+ super.setFilter(filter);
+ }
+
+ @Override
+ public TextFilter getFilter() {
+ return super.getFilter();
+ }
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/RowHeaderRecyclerAdapter.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/RowHeaderRecyclerAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ccf47acd0b248b55566bf846e96f0a40dd98118
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/adapter/RowHeaderRecyclerAdapter.java
@@ -0,0 +1,86 @@
+package com.test.tableview.adapter;
+
+import com.test.tableview.ResourceTable;
+import com.test.tableview.model.Cell;
+import ohos.agp.components.Component;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.RecycleItemProvider;
+import ohos.agp.components.Text;
+import ohos.agp.components.element.ShapeElement;
+import ohos.app.Context;
+
+import java.util.List;
+
+/**
+ * 表格行头数据适配器
+ *
+ */
+public class RowHeaderRecyclerAdapter extends RecycleItemProvider {
+
+ /**
+ * 数据集合
+ */
+ private List cells;
+
+ /**
+ * 上下文对象
+ */
+ private Context context;
+
+ /**
+ * 构造函数
+ *
+ * @param cells 单元格数据集
+ * @param context 上下文内容对象
+ */
+ public RowHeaderRecyclerAdapter(List cells, Context context) {
+ this.cells = cells;
+ this.context = context;
+ }
+
+
+ public List getItems() {
+ return cells;
+ }
+
+
+ @Override
+ public int getCount() {
+ return cells.size();
+ }
+
+ @Override
+ public Cell getItem(int i) {
+ return cells.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+
+ @Override
+ public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
+ if (position >= cells.size()) {
+ return null;
+ }
+ Component component = convertComponent;
+ if (component == null) {
+ component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_cell_item, null, false);
+ }
+ Cell cell = cells.get(position);
+ Text text = (Text) component.findComponentById(ResourceTable.Id_cell_item);
+ text.setText(cell.getData());
+ ShapeElement shapeElement = new ShapeElement();
+ shapeElement.setRgbColor(cell.getRgbColor());
+ text.setBackground(shapeElement);
+ return component;
+ }
+
+ @Override
+ public int getComponentTypeCount() {
+ return 2;
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/layoutmanager/FitWidthUtils.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/layoutmanager/FitWidthUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..0075847aa53787d5a7d360496cd06547a5eb6e3e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/layoutmanager/FitWidthUtils.java
@@ -0,0 +1,64 @@
+package com.test.tableview.layoutmanager;
+
+import com.test.tableview.model.Cell;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 宽度自适应类
+ *
+ */
+public class FitWidthUtils {
+
+ /**
+ * 单元格宽度
+ */
+ private static final int CELL_WIDTH = 35;
+
+ /**
+ * 获取每列自适应的列宽长度集合
+ *
+ * @param colHeads 列头集合
+ * @param allCells 所有单元格集合
+ * @return 每列自适应的列宽长度集合
+ */
+ public static List fitColWidthSize(List colHeads, List> allCells) {
+ List result = new ArrayList<>();
+ Map> map = new HashMap<>();
+ for (int index = 0; index < colHeads.size(); index++) {
+ map.put(index, new ArrayList<>());
+ }
+ for (List cells : allCells) {
+ for (int index = 0; index < cells.size(); index++) {
+ int dataLen = cells.get(index).getData().length();
+ map.get(index).add(fitWidthSize(dataLen));
+ }
+ }
+ for (int index = 0; index < colHeads.size(); index++) {
+ List list = map.get(index);
+ Collections.sort(list);
+ result.add(list.get(list.size() - 1));
+ }
+ return result;
+
+ }
+
+ /**
+ * 自适应宽度
+ *
+ * @param dataLen 数据长度
+ * @return 自适应宽度
+ */
+ private static int fitWidthSize(int dataLen) {
+ int count = dataLen / 5;
+ if (dataLen % 5 == 0) {
+ return CELL_WIDTH * count * 3;
+ }
+ return CELL_WIDTH * (count + 1) * 3;
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/listener/filter/FilterListener.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/listener/filter/FilterListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d9cd8571b49024dc6de47a4c73ed95310514df3
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/listener/filter/FilterListener.java
@@ -0,0 +1,120 @@
+package com.test.tableview.listener.filter;
+
+import com.test.tableview.TableView;
+import com.test.tableview.adapter.CellRecyclerViewAdapter;
+import com.test.tableview.adapter.RowHeaderRecyclerAdapter;
+import com.test.tableview.model.Cell;
+import ohos.agp.components.Component;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 过滤监听
+ *
+ */
+public class FilterListener {
+
+ /**
+ * 过滤关键字
+ */
+ private String filterText;
+
+ /**
+ * table表对象
+ */
+ private TableView tableView;
+
+ /**
+ * 过滤监听
+ */
+ private Component.ClickedListener filter;
+
+ /**
+ * 构造器
+ *
+ * @param tableView 表对象
+ * @param filterText 过滤文本
+ */
+ public FilterListener(TableView tableView, String filterText) {
+ this.tableView = tableView;
+ this.filterText = filterText;
+ initFilter();
+ }
+
+ /**
+ * 初始化过滤器
+ */
+ public void initFilter() {
+ filterText = filterText.trim();
+ if ("".equals(filterText)) {
+ tableView.initView(tableView.getDataModel());
+ return;
+ }
+ List filterRowHeads = new ArrayList<>();
+ List> filterCells = new ArrayList<>();
+ List> allCells = tableView.getCellRecyclerViewAdapter().getItems();
+ List rowHeads = tableView.getRowHeaderRecyclerAdapter().getItems();
+
+ for (int index = 0; index < allCells.size(); index++) {
+ List rowCells = allCells.get(index);
+ if (rowHeads.get(index).getData().contains(filterText)) {
+ filterCells.add(rowCells);
+ filterRowHeads.add(rowHeads.get(index));
+ } else {
+ for (Cell cell : rowCells) {
+ if (cell.getData().contains(filterText)) {
+ filterCells.add(rowCells);
+ filterRowHeads.add(rowHeads.get(index));
+ break;
+ }
+ }
+ }
+ }
+ CellRecyclerViewAdapter cellRecyclerViewAdapter = new CellRecyclerViewAdapter(filterCells, tableView.getContext());
+ tableView.getContainerModel().getCellContainer().setItemProvider(cellRecyclerViewAdapter);
+ RowHeaderRecyclerAdapter rowHeaderRecyclerAdapter = new RowHeaderRecyclerAdapter(filterRowHeads, tableView.getContext());
+ tableView.getContainerModel().getRowHeadContainer().setItemProvider(rowHeaderRecyclerAdapter);
+// filter = new Component.ClickedListener() {
+// @Override
+// public void onClick(Component component) {
+// filterText = filterText.trim();
+// if ("".equals(filterText)) {
+// tableView.initView(tableView.getDataModel());
+// return;
+// }
+// List filterRowHeads = new ArrayList<>();
+// List> filterCells = new ArrayList<>();
+// List> allCells = tableView.getCellRecyclerViewAdapter().getItems();
+// List rowHeads = tableView.getRowHeaderRecyclerAdapter().getItems();
+//
+// for (int index = 0; index < allCells.size(); index++) {
+// List rowCells = allCells.get(index);
+// if (rowHeads.get(index).getData().contains(filterText)) {
+// filterCells.add(rowCells);
+// filterRowHeads.add(rowHeads.get(index));
+// } else {
+// for (Cell cell : rowCells) {
+// if (cell.getData().contains(filterText)) {
+// filterCells.add(rowCells);
+// filterRowHeads.add(rowHeads.get(index));
+// break;
+// }
+// }
+// }
+// }
+// CellRecyclerViewAdapter cellRecyclerViewAdapter = new CellRecyclerViewAdapter(filterCells, tableView.getContext());
+// tableView.getContainerModel().getCellContainer().setItemProvider(cellRecyclerViewAdapter);
+// RowHeaderRecyclerAdapter rowHeaderRecyclerAdapter = new RowHeaderRecyclerAdapter(filterRowHeads, tableView.getContext());
+// tableView.getContainerModel().getRowHeadContainer().setItemProvider(rowHeaderRecyclerAdapter);
+// }
+// };
+ }
+
+ public Component.ClickedListener getFilter() {
+ return filter;
+ }
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/listener/itemclick/TableItemClickListeners.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/listener/itemclick/TableItemClickListeners.java
new file mode 100644
index 0000000000000000000000000000000000000000..8836f56d55fc59df4f6f734be0c99481f5cac10a
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/listener/itemclick/TableItemClickListeners.java
@@ -0,0 +1,233 @@
+package com.test.tableview.listener.itemclick;
+
+import com.test.tableview.TableView;
+import com.test.tableview.adapter.CellRecyclerViewAdapter;
+import com.test.tableview.adapter.CellRowRecyclerViewAdapter;
+import com.test.tableview.adapter.ColumnHeaderRecyclerAdapter;
+import com.test.tableview.model.Cell;
+import ohos.agp.colors.RgbColor;
+import ohos.agp.components.Component;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.element.ShapeElement;
+import ohos.app.Context;
+
+import java.util.List;
+
+/**
+ * 表格点击事件监听
+ *
+ */
+public class TableItemClickListeners {
+
+ /**
+ * 白色
+ */
+ private static final RgbColor WHITE_RGB = new RgbColor(255, 255, 255);
+
+ /**
+ * 绿色
+ */
+ private static final RgbColor GREEN_RGB = new RgbColor(0, 255, 0);
+
+ /**
+ * 蓝色
+ */
+ private static final RgbColor BLUE_RGB = new RgbColor(0, 0, 255);
+
+ /**
+ * table视图对象
+ */
+ private TableView tableView;
+
+ /**
+ * 上下文对象
+ */
+ private Context context;
+
+ /**
+ * 行头点击监听事件
+ */
+ private ListContainer.ItemClickedListener rowHeadClickListener;
+
+ /**
+ * 列头点击监听事件
+ */
+ private ListContainer.ItemClickedListener columnHeadClickListener;
+
+ /**
+ * 单元格点击监听事件
+ */
+ private ListContainer.ClickedListener cellClickListener;
+
+ /**
+ * 构造器
+ *
+ * @param tableView 表对象
+ * @param context 上下文对象
+ */
+ public TableItemClickListeners(TableView tableView, Context context) {
+ this.tableView = tableView;
+ this.context = context;
+ initListeners();
+ }
+
+
+ /**
+ * 初始化监听事件
+ */
+ private void initListeners() {
+ initRowHeadClickListener();
+ initColumnHeadClickListener();
+ initCellClickListener();
+ }
+
+ /**
+ * 初始化单元格点击监听事件
+ */
+ private void initCellClickListener() {
+ cellClickListener = new ListContainer.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ ShapeElement element = new ShapeElement();
+ element.setRgbColor(BLUE_RGB);
+ component.setBackground(element);
+ }
+ };
+ }
+
+ /**
+ * 初始化行头点击监听事件
+ */
+ private void initRowHeadClickListener() {
+ rowHeadClickListener = new ListContainer.ItemClickedListener() {
+ @Override
+ public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
+ List rowHeadList = tableView.getRowHeaderRecyclerAdapter().getItems();
+ Cell rowHead = rowHeadList.get(i);
+ List> allCells = tableView.getCellRecyclerViewAdapter().getItems();
+ List rowCells = allCells.get(i);
+ List colHeadCells = tableView.getColumnHeaderRecyclerAdapter().getItems();
+ // 之前已颜色渲染此行,点击清除颜色
+ if (!isWhiteColor(rowHead.getRgbColor())) {
+ rowHead.setRgbColor(WHITE_RGB);
+ for (Cell cell : rowCells) {
+ cell.setRgbColor(WHITE_RGB);
+ }
+ } else {
+ // 之前未颜色渲染此行,渲染颜色
+ rowHead.setRgbColor(GREEN_RGB);
+ for (int index = 0; index < rowCells.size(); index++) {
+ Cell cell = rowCells.get(index);
+ if (!isWhiteColor(cell.getRgbColor())) {
+ Cell colHead = colHeadCells.get(index);
+ colHead.setRgbColor(WHITE_RGB);
+ for (List allRowcells : allCells) {
+ allRowcells.get(index).setRgbColor(WHITE_RGB);
+ }
+ }
+ cell.setRgbColor(GREEN_RGB);
+ }
+ }
+
+ ListContainer cellsContainer = tableView.getContainerModel().getCellContainer();
+ CellRecyclerViewAdapter cellRecyclerViewAdapter = new CellRecyclerViewAdapter(allCells.subList(cellsContainer.getFirstVisibleItemPosition(),
+ cellsContainer.getLastVisibleItemPosition()), context);
+ cellsContainer.setItemProvider(cellRecyclerViewAdapter);
+
+ ListContainer rowHeadContainer = tableView.getContainerModel().getRowHeadContainer();
+ CellRowRecyclerViewAdapter cellRowRecyclerViewAdapter = new CellRowRecyclerViewAdapter(rowHeadList.subList(rowHeadContainer.getFirstVisibleItemPosition(),
+ rowHeadContainer.getLastVisibleItemPosition()), context);
+ rowHeadContainer.setItemProvider(cellRowRecyclerViewAdapter);
+
+ ColumnHeaderRecyclerAdapter columnHeaderRecyclerAdapter = new ColumnHeaderRecyclerAdapter(colHeadCells, context);
+ tableView.getContainerModel().getColumnHeadContainer().setItemProvider(columnHeaderRecyclerAdapter);
+ }
+ };
+ }
+
+ /**
+ * 初始化列头点击监听事件
+ */
+ private void initColumnHeadClickListener() {
+ columnHeadClickListener = new ListContainer.ItemClickedListener() {
+ @Override
+ public void onItemClicked(ListContainer listContainer, Component component, int xPosition, long l) {
+ List colHeads = tableView.getColumnHeaderRecyclerAdapter().getItems();
+ Cell colHead = colHeads.get(xPosition);
+ List> allCells = tableView.getCellRecyclerViewAdapter().getItems();
+ List rowHeads = tableView.getRowHeaderRecyclerAdapter().getItems();
+ // 之前已颜色渲染此列,点击清除颜色
+ if (!isWhiteColor(colHead.getRgbColor())) {
+ colHead.setRgbColor(WHITE_RGB);
+ for (List cellList : allCells) {
+ for (int index = 0; index < cellList.size(); index++) {
+ Cell c = cellList.get(index);
+ if (!isWhiteColor(c.getRgbColor()) && isWhiteColor(colHeads.get(index).getRgbColor())) {
+ c.setRgbColor(WHITE_RGB);
+ Cell rowKey = rowHeads.get(index);
+ rowKey.setRgbColor(WHITE_RGB);
+ }
+ }
+ Cell cell = cellList.get(xPosition);
+ cell.setRgbColor(WHITE_RGB);
+ }
+ } else {
+ // 之前未颜色渲染此列,渲染颜色
+ colHead.setRgbColor(GREEN_RGB);
+
+ for (int index = 0; index < allCells.size(); index++) {
+ List rowCells = allCells.get(index);
+ Cell cell = rowCells.get(xPosition);
+ if (!isWhiteColor(cell.getRgbColor())) {
+ // 清除 index 行的颜色后在渲染此列的颜色
+ for (Cell rowCell : rowCells) {
+ rowCell.setRgbColor(WHITE_RGB);
+ }
+ Cell rowHeadCell = rowHeads.get(index);
+ rowHeadCell.setRgbColor(WHITE_RGB);
+
+ }
+ cell.setRgbColor(GREEN_RGB);
+ }
+
+ }
+ ListContainer cellsContainer = tableView.getContainerModel().getCellContainer();
+ CellRecyclerViewAdapter cellRecyclerViewAdapter = new CellRecyclerViewAdapter(allCells.subList(cellsContainer.getFirstVisibleItemPosition(),
+ cellsContainer.getLastVisibleItemPosition()), context);
+ cellsContainer.setItemProvider(cellRecyclerViewAdapter);
+
+ ListContainer rowHeadContainer = tableView.getContainerModel().getRowHeadContainer();
+ CellRowRecyclerViewAdapter cellRowRecyclerViewAdapter = new CellRowRecyclerViewAdapter(rowHeads.subList(rowHeadContainer.getFirstVisibleItemPosition(),
+ rowHeadContainer.getLastVisibleItemPosition()), context);
+ rowHeadContainer.setItemProvider(cellRowRecyclerViewAdapter);
+
+ ColumnHeaderRecyclerAdapter columnHeaderRecyclerAdapter = new ColumnHeaderRecyclerAdapter(colHeads, context);
+ tableView.getContainerModel().getColumnHeadContainer().setItemProvider(columnHeaderRecyclerAdapter);
+ }
+ };
+ }
+
+ /**
+ * 判断是不是白色
+ *
+ * @param rgbColor 颜色
+ * @return true/false
+ */
+ private boolean isWhiteColor(RgbColor rgbColor) {
+ return rgbColor.getRed() == WHITE_RGB.getRed() && rgbColor.getBlue() == WHITE_RGB.getBlue() && rgbColor.getGreen() == WHITE_RGB.getGreen();
+ }
+
+ public ListContainer.ItemClickedListener getRowHeadClickListener() {
+ return rowHeadClickListener;
+ }
+
+ public ListContainer.ItemClickedListener getColumnHeadClickListener() {
+ return columnHeadClickListener;
+ }
+
+ public ListContainer.ClickedListener getCellClickListener() {
+ return cellClickListener;
+ }
+
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/model/Cell.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/model/Cell.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6ee329ffe5e12becac61bd2f3e17a7134986d10
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/model/Cell.java
@@ -0,0 +1,87 @@
+package com.test.tableview.model;
+
+import ohos.agp.colors.RgbColor;
+
+/**
+ * 单元格对象
+ *
+ */
+public class Cell {
+
+ /**
+ * id
+ */
+ private String id;
+
+ /**
+ * 单元格内容
+ */
+ private String data;
+
+ /**
+ * 单元格颜色
+ */
+ private RgbColor rgbColor = new RgbColor(255, 255, 255);
+
+ /**
+ * 单元格宽度
+ */
+ private int width = 0;
+
+ /**
+ * 构造器
+ *
+ * @param id id
+ * @param data 单元格内容
+ */
+ public Cell(String id, String data) {
+ this.id = id;
+ this.data = data;
+ }
+
+
+ /**
+ * 构造器
+ *
+ * @param id id
+ * @param data 单元格内容
+ * @param width 宽度
+ */
+ public Cell(String id, String data, int width) {
+ this.id = id;
+ this.data = data;
+ this.width = width;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public RgbColor getRgbColor() {
+ return rgbColor;
+ }
+
+ public void setRgbColor(RgbColor rgbColor) {
+ this.rgbColor = rgbColor;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/pagination/IPagination.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/pagination/IPagination.java
new file mode 100644
index 0000000000000000000000000000000000000000..d71276be8140490bf75f24e686e57506c2e72be2
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/pagination/IPagination.java
@@ -0,0 +1,65 @@
+package com.test.tableview.pagination;
+
+/**
+ * 分页接口
+ *
+ */
+public interface IPagination {
+
+ /**
+ * Loads the next page of the data set to the table view.
+ */
+ void nextPage();
+
+ /**
+ * Loads the previous page of the data set to the table view.
+ */
+ void previousPage();
+
+ /**
+ * Loads the data set of the specified page to the table view.
+ *
+ * @param page The page to be loaded.
+ */
+ void goToPage(int page);
+
+ /**
+ * Sets the number of items (rows) per page to be displayed in the table view.
+ *
+ * @param numItems The number of items per page.
+ */
+ void setItemsPerPage(int numItems);
+
+ /**
+ * Sets the OnTableViewPageTurnedListener for this Pagination.
+ *
+ * @param onTableViewPageTurnedListener The OnTableViewPageTurnedListener.
+ */
+ void setTableViewPageTurnedListener(Pagination.OnTableViewPageTurnedListener onTableViewPageTurnedListener);
+
+ /**
+ * Removes the OnTableViewPageTurnedListener for this Pagination.
+ */
+ void removePageTurnedListener();
+
+ /**
+ * @return The current page loaded to the table view.
+ */
+ int getCurrentPage();
+
+ /**
+ * @return The number of items per page loaded to the table view.
+ */
+ int getItemsPerPage();
+
+ /**
+ * @return The number of pages in the pagination.
+ */
+ int getPageCount();
+
+ /**
+ * @return Current pagination state of the table view.
+ */
+ boolean isPaginated();
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/pagination/Pagination.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/pagination/Pagination.java
new file mode 100644
index 0000000000000000000000000000000000000000..efcbfcf57a10b0fbed4277b3fb8916325425c22a
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/pagination/Pagination.java
@@ -0,0 +1,227 @@
+package com.test.tableview.pagination;
+
+import com.test.tableview.TableView;
+import com.test.tableview.adapter.CellRecyclerViewAdapter;
+import com.test.tableview.adapter.RowHeaderRecyclerAdapter;
+import com.test.tableview.model.Cell;
+import ohos.agp.components.ListContainer;
+import ohos.app.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 分页
+ *
+ */
+public class Pagination implements IPagination {
+
+ /**
+ * 默认每页记录数
+ */
+ private static final int DEFAULT_ITEMS_PER_PAGE = 50;
+
+ /**
+ * 每页记录数
+ */
+ private int itemsPerPage;
+ /**
+ * 当前页
+ */
+ private int currentPage;
+
+ /**
+ * 总页数
+ */
+ private int pageCount;
+
+ /**
+ * 单元格数据集
+ */
+ private List> originalCellData;
+
+ /**
+ * 表行头数据集
+ */
+ private List originalRowData;
+
+ /**
+ * 页码跳转监听
+ */
+ private OnTableViewPageTurnedListener onTableViewPageTurnedListener;
+
+ /**
+ * 表对象
+ */
+ private TableView tableView;
+
+ /**
+ * 上下文对象
+ */
+ private Context context;
+
+
+ /**
+ * 构造器
+ *
+ * @param tableView 表对象
+ * @param context 上下文对象
+ */
+ public Pagination(TableView tableView, Context context) {
+ this.tableView = tableView;
+ this.context = context;
+ initialize(DEFAULT_ITEMS_PER_PAGE, null);
+ }
+
+
+ /**
+ * 构造器
+ *
+ * @param tableView 表对象
+ * @param context 上下文对象
+ * @param itemsPerPage 每页记录数
+ * @param listener 监听
+ */
+ public Pagination(TableView tableView, Context context, int itemsPerPage, OnTableViewPageTurnedListener listener) {
+ this.tableView = tableView;
+ this.context = context;
+ initialize(itemsPerPage, listener);
+ }
+
+ /**
+ * 初始化
+ *
+ * @param itemsPerPage 每页记录数
+ * @param listener 页码跳转监听
+ */
+ private void initialize(int itemsPerPage, OnTableViewPageTurnedListener listener) {
+ this.onTableViewPageTurnedListener = listener;
+ this.itemsPerPage = itemsPerPage;
+ this.originalCellData = tableView.getCellRecyclerViewAdapter().getItems();
+ this.originalRowData = tableView.getRowHeaderRecyclerAdapter().getItems();
+ this.currentPage = 1;
+ reloadPages();
+ }
+
+ /**
+ * 重新分页
+ */
+ private void reloadPages() {
+ goToPage(currentPage);
+ }
+
+ /**
+ * 分页
+ */
+ private void paginateData() {
+ int start;
+ int end;
+ List> currentPageCellData = new ArrayList<>();
+ List currentPageRowData = new ArrayList<>();
+ // No pagination if itemsPerPage is 0, all data will be loaded into the TableView.
+ if (itemsPerPage == 0) {
+ currentPageCellData.addAll(originalCellData);
+ currentPageRowData.addAll(originalRowData);
+ pageCount = 1;
+ start = 0;
+ end = currentPageCellData.size();
+ } else {
+ start = (currentPage * itemsPerPage) - itemsPerPage;
+ end = (currentPage * itemsPerPage) > originalCellData.size() ?
+ originalCellData.size() : (currentPage * itemsPerPage);
+
+ for (int x = start; x < end; x++) {
+ currentPageCellData.add(originalCellData.get(x));
+ currentPageRowData.add(originalRowData.get(x));
+ }
+
+ // Using ceiling to calculate number of pages, e.g. 103 items of 10 items per page
+ // will result to 11 pages.
+ pageCount = (int) Math.ceil((double) originalCellData.size() / itemsPerPage);
+ }
+
+ ListContainer cellContainer = tableView.getContainerModel().getCellContainer();
+ ListContainer rowHeadContainer = tableView.getContainerModel().getRowHeadContainer();
+
+ CellRecyclerViewAdapter cellRecyclerViewAdapter = new CellRecyclerViewAdapter(currentPageCellData, context);
+ cellContainer.setItemProvider(cellRecyclerViewAdapter);
+
+ RowHeaderRecyclerAdapter rowHeaderRecyclerAdapter = new RowHeaderRecyclerAdapter(currentPageRowData, context);
+ rowHeadContainer.setItemProvider(rowHeaderRecyclerAdapter);
+
+ // Dispatches TableView changes to Listener interface
+ if (onTableViewPageTurnedListener != null) {
+ onTableViewPageTurnedListener.onPageTurned(currentPageCellData.size(), start, end - 1);
+ }
+ }
+
+ @Override
+ public void nextPage() {
+ currentPage = currentPage + 1 > pageCount ? currentPage : ++currentPage;
+ paginateData();
+ }
+
+ @Override
+ public void previousPage() {
+ currentPage = currentPage - 1 == 0 ? currentPage : --currentPage;
+ paginateData();
+ }
+
+ @Override
+ public void goToPage(int page) {
+ currentPage = (page > pageCount || page < 1) ? (page > pageCount && pageCount > 0 ? pageCount : currentPage) : page;
+ paginateData();
+ }
+
+ @Override
+ public void setItemsPerPage(int numItems) {
+ itemsPerPage = numItems;
+ currentPage = 1;
+ paginateData();
+ }
+
+ @Override
+ public void setTableViewPageTurnedListener(OnTableViewPageTurnedListener onTableViewPageTurnedListener) {
+ this.onTableViewPageTurnedListener = onTableViewPageTurnedListener;
+ }
+
+ @Override
+ public void removePageTurnedListener() {
+ this.onTableViewPageTurnedListener = null;
+ }
+
+ @Override
+ public int getCurrentPage() {
+ return currentPage;
+ }
+
+ @Override
+ public int getItemsPerPage() {
+ return itemsPerPage;
+ }
+
+ @Override
+ public int getPageCount() {
+ return pageCount;
+ }
+
+ @Override
+ public boolean isPaginated() {
+ return itemsPerPage > 0;
+ }
+
+ /**
+ * Listener interface for changing of TableView page.
+ */
+ public interface OnTableViewPageTurnedListener {
+
+ /**
+ * Called when the page is changed in the TableView.
+ *
+ * @param numItems The number of items currently being displayed in the TableView.
+ * @param itemsStart The starting item currently being displayed in the TableView.
+ * @param itemsEnd The ending item currently being displayed in the TableView.
+ */
+ void onPageTurned(int numItems, int itemsStart, int itemsEnd);
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/scroll/ScrollUtils.java b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/scroll/ScrollUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..39a53d7963e6299092a9be1fb746a2717ee226ed
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/java/com/test/tableview/scroll/ScrollUtils.java
@@ -0,0 +1,86 @@
+package com.test.tableview.scroll;
+
+import ohos.agp.components.Component;
+import ohos.agp.components.NestedScrollView;
+
+/**
+ * 滚动工具类
+ *
+ */
+public class ScrollUtils {
+
+ /**
+ * 列头滚动组件
+ */
+ private NestedScrollView colHeadScroll;
+
+ /**
+ * 行头滚动组件
+ */
+ private NestedScrollView rowHeadScroll;
+
+ /**
+ * 内容滚动组件
+ */
+ private NestedScrollView cellsScroll;
+
+ /**
+ * x方向位置
+ */
+ private int xPosition = 0;
+ /**
+ * 方向位置
+ */
+ private int yPosition = 0;
+
+
+ /**
+ * 构造器
+ *
+ * @param colHeadScroll 列头滚动组件
+ * @param rowHeadScroll 行头滚动组件
+ * @param cellsScroll 内容滚动组件
+ */
+ public ScrollUtils(NestedScrollView colHeadScroll, NestedScrollView rowHeadScroll, NestedScrollView cellsScroll) {
+ this.colHeadScroll = colHeadScroll;
+ this.rowHeadScroll = rowHeadScroll;
+ this.cellsScroll = cellsScroll;
+ }
+
+
+ /**
+ * 设置同步滑动
+ */
+ public void scroll() {
+
+ colHeadScroll.setScrolledListener(new NestedScrollView.ScrolledListener() {
+ @Override
+ public void onContentScrolled(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ cellsScroll.scrollTo(scrollX, yPosition);
+ xPosition = scrollX;
+ }
+ });
+
+ rowHeadScroll.setScrolledListener(new NestedScrollView.ScrolledListener() {
+ @Override
+ public void onContentScrolled(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ cellsScroll.scrollTo(xPosition, scrollY);
+ yPosition = scrollY;
+ }
+ });
+
+ cellsScroll.setScrolledListener(new NestedScrollView.ScrolledListener() {
+ @Override
+ public void onContentScrolled(Component component, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
+ if (Math.abs(scrollY - oldScrollY) > Math.abs(scrollX - oldScrollX)) {
+ rowHeadScroll.scrollTo(scrollX, scrollY);
+ } else if ((Math.abs(scrollY - oldScrollY) < Math.abs(scrollX - oldScrollX))) {
+ // 水平滚动
+ colHeadScroll.scrollTo(scrollX, scrollY);
+ }
+ }
+ });
+ }
+
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/element/integer.json b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/element/integer.json
new file mode 100644
index 0000000000000000000000000000000000000000..134e156e3a21ee8fa3fdfa00b23a092409c38d00
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/element/integer.json
@@ -0,0 +1,16 @@
+{
+ "integer": [
+ {
+ "name": "cell_height",
+ "value": 20
+ },
+ {
+ "name": "cell_width",
+ "value": 80
+ },
+ {
+ "name": "cell_text_size",
+ "value": 10
+ }
+ ]
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/element/string.json b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..0a629a10c2814a63d2904a5c7ba225c2d5c9d203
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/element/string.json
@@ -0,0 +1,20 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "TableView"
+ },
+ {
+ "name": "cell_height",
+ "value": "20fp"
+ },
+ {
+ "name": "cell_width",
+ "value": "50fp"
+ },
+ {
+ "name": "cell_text_size",
+ "value": "10fp"
+ }
+ ]
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/graphic/happy_icon.xml b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/graphic/happy_icon.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8ccb748b05bb0bf600f4a36d97abe53b652bdf28
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/graphic/happy_icon.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/layout/cell_item.xml b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/layout/cell_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..92ddb4351ab184b22b939cd5ba39f6e17f64230e
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/layout/cell_item.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/layout/cell_row.xml b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/layout/cell_row.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b6722fe3da9ba6596cd00058a6ef461cafa7a470
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/tableview/src/main/resources/base/layout/cell_row.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/.gitignore b/018.TableView_OpenHarmony-master/TableView/testtableview/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/build.gradle b/018.TableView_OpenHarmony-master/TableView/testtableview/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..fa8c82ec585f792f279d67fd11285261bbde7a74
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+ entryModules "entry"
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/libs/tableview-debug.har b/018.TableView_OpenHarmony-master/TableView/testtableview/libs/tableview-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..5dcac2ba95e767557f55fd80d14fb1a8505819e2
Binary files /dev/null and b/018.TableView_OpenHarmony-master/TableView/testtableview/libs/tableview-debug.har differ
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/config.json b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..51ef85d32e0bdb315833f3841e2b6685f142b8ac
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/config.json
@@ -0,0 +1,40 @@
+{
+ "app": {
+ "bundleName": "com.example.myharmonyapp",
+ "vendor": "test",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.test.testtableview",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "testtableview",
+ "moduleType": "feature"
+ },
+ "abilities": [
+ {
+ "orientation": "unspecified",
+ "visible": true,
+ "name": "com.test.testtableview.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "TestTableview",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/DataModelTest.java b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/DataModelTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..29569aa051c4cc965db0f28e2a9d07a20f62dfb7
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/DataModelTest.java
@@ -0,0 +1,94 @@
+package com.test.testtableview;
+
+import com.test.tableview.IDataModel;
+import com.test.tableview.model.Cell;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * 测试数据
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class DataModelTest implements IDataModel {
+
+ /**
+ * table表行数
+ */
+ private static final int ROW_SIZE = 115;
+
+ /**
+ * table表列数
+ */
+ private static final int COLUMN_SIZE = 7;
+
+ /**
+ * 获取表内容数据集
+ *
+ * @return 表内容数据集
+ */
+ public List> getCellList() {
+ List> list = new ArrayList<>();
+ for (int i = 0; i < ROW_SIZE; i++) {
+ List cellList = new ArrayList<>();
+ for (int j = 0; j < COLUMN_SIZE; j++) {
+ Object text = "cell " + j + " " + i;
+ final int random = new Random().nextInt();
+ if (j == 0) {
+ text = i;
+ } else if (j == 1) {
+ text = random;
+ }
+
+ // Create dummy id.
+ String id = j + "-" + i;
+
+ Cell cell;
+ String data = String.valueOf(text);
+ if (j == 3) {
+ cell = new Cell(id, data);
+ } else if (j == 4) {
+ cell = new Cell(id, data);
+ } else {
+ cell = new Cell(id, data);
+ }
+ cellList.add(cell);
+ }
+ list.add(cellList);
+ }
+
+ return list;
+ }
+
+ /**
+ * 获取表头数据集
+ *
+ * @return 表头数据集
+ */
+ public List getColumnHeads() {
+ List cells = new ArrayList<>();
+ for (int i = 0; i < COLUMN_SIZE; i++) {
+ Cell cell = new Cell(String.valueOf(i), "col" + i);
+ cells.add(cell);
+ }
+ return cells;
+ }
+
+ /**
+ * 获取每行第一列数据集
+ *
+ * @return 每行第一列数据集
+ */
+ public List getRowHeads() {
+ List cells = new ArrayList<>();
+ for (int i = 0; i < ROW_SIZE; i++) {
+ Cell cell = new Cell(String.valueOf(i), "row" + i);
+ cells.add(cell);
+ }
+ return cells;
+ }
+
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/MainAbility.java b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0655fbec990cb344905ba17e5d1509b7ee774da
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/MainAbility.java
@@ -0,0 +1,19 @@
+package com.test.testtableview;
+
+import com.test.testtableview.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+/**
+ * 程序入口
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/MyApplication.java b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..72824e734e9f0456eee6146dcedc191ba86eada5
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/MyApplication.java
@@ -0,0 +1,16 @@
+package com.test.testtableview;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * MyApplication
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/slice/MainAbilitySlice.java b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa82dd9969cb4528c3da7d6d462eead01a017dd6
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/java/com/test/testtableview/slice/MainAbilitySlice.java
@@ -0,0 +1,104 @@
+package com.test.testtableview.slice;
+
+import com.test.tableview.ContainerModel;
+import com.test.tableview.TableView;
+import com.test.tableview.listener.itemclick.TableItemClickListeners;
+import com.test.tableview.scroll.ScrollUtils;
+import com.test.testtableview.DataModelTest;
+import com.test.testtableview.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.ListContainer;
+import ohos.agp.components.NestedScrollView;
+
+/**
+ * 主线程
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class MainAbilitySlice extends AbilitySlice {
+
+ /**
+ * 列头视图模型
+ */
+ private ListContainer columnHeadContainer;
+
+ /**
+ * 行头视图模型
+ */
+ private ListContainer rowHeadContainer;
+
+ /**
+ * 单元格视图模型
+ */
+ private ListContainer cellContainer;
+
+ /**
+ * 滚动组件
+ */
+ private NestedScrollView colHeadScroll;
+
+ /**
+ * 滚动组件
+ */
+ private NestedScrollView rowHeadScroll;
+
+ /**
+ * 滚动组件
+ */
+ private NestedScrollView cellsScroll;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ colHeadScroll = (NestedScrollView) findComponentById(ResourceTable.Id_col_head_scroll);
+ rowHeadScroll = (NestedScrollView) findComponentById(ResourceTable.Id_row_head_scroll);
+ cellsScroll = (NestedScrollView) findComponentById(ResourceTable.Id_cells_scroll);
+
+ columnHeadContainer = (ListContainer) findComponentById(ResourceTable.Id_column_head_container);
+ rowHeadContainer = (ListContainer) findComponentById(ResourceTable.Id_row_head_container);
+ cellContainer = (ListContainer) findComponentById(ResourceTable.Id_cells_container);
+ DataModelTest dataModel = new DataModelTest();
+ ContainerModel containerModel = new ContainerModel(columnHeadContainer, rowHeadContainer, cellContainer);
+
+ TableView tableView = new TableView(this, dataModel, containerModel);
+ initTableView(tableView);
+
+ }
+
+ /**
+ * 初始话table视图
+ *
+ * @param tableView table视图对象
+ */
+ private void initTableView(TableView tableView) {
+ TableItemClickListeners tableListener = new TableItemClickListeners(tableView, getContext());
+ rowHeadContainer.setItemClickedListener(tableListener.getRowHeadClickListener());
+ columnHeadContainer.setItemClickedListener(tableListener.getColumnHeadClickListener());
+ cellContainer.setClickedListener(tableListener.getCellClickListener());
+
+ rowHeadContainer.setItemProvider(tableView.getRowHeaderRecyclerAdapter());
+ columnHeadContainer.setItemProvider(tableView.getColumnHeaderRecyclerAdapter());
+
+ cellContainer.setItemProvider(tableView.getCellRecyclerViewAdapter());
+
+
+ // 设置同步滑动
+ ScrollUtils scrollUtils = new ScrollUtils(colHeadScroll, rowHeadScroll, cellsScroll);
+ scrollUtils.scroll();
+
+
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/element/string.json b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..b81b1371d12e73ef08366cbc43c6fe19ee15ecc5
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/element/string.json
@@ -0,0 +1,20 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "TestTableview"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "list_view_width",
+ "value": "3000vp"
+ },
+ {
+ "name": "list_view_height",
+ "value": "3000vp"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/graphic/background_ability_main.xml b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/layout/ability_main.xml b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3c293d35801b90e11abe645b1bca35f19032302c
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/media/icon.png b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/018.TableView_OpenHarmony-master/TableView/testtableview/src/main/resources/base/media/icon.png differ
diff --git a/018.TableView_OpenHarmony-master/TableView/testtableview/src/test/java/com/test/testtableview/ExampleTest.java b/018.TableView_OpenHarmony-master/TableView/testtableview/src/test/java/com/test/testtableview/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2aaab7407822706c28f537c63ca2245e84a7e45c
--- /dev/null
+++ b/018.TableView_OpenHarmony-master/TableView/testtableview/src/test/java/com/test/testtableview/ExampleTest.java
@@ -0,0 +1,18 @@
+package com.test.testtableview;
+
+import org.junit.Test;
+/**
+ * 测试类
+ *
+ * @author yanwangcr
+ * @since 2021/02/18
+ */
+public class ExampleTest {
+
+ /**
+ * 测试方法
+ */
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.gitignore b/019.CircleIndicatorComponent_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/.gitignore b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/codemars.log b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/codemars.log
new file mode 100644
index 0000000000000000000000000000000000000000..3f7440ac3ba8b0ebc64dbd6d172339b5709bb404
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/codemars.log
@@ -0,0 +1,29 @@
+2021-01-25 08:22:41.965 [main] INFO . - user input: D:\tools\DevEco Studio\jbr\bin\java,-j,-source,@E:/DecosCode/Test/.idea/code-check/java/detect.txt,-output,E:/DecosCode/Test/.idea/code-check/java/output.xml
+2021-01-25 08:22:41.971 [main] INFO . - CodeMars Version:2.1.2.sp4
+2021-01-25 08:22:42.236 [main] INFO . - starting analyzing.
+2021-01-25 08:22:42.270 [main] INFO . - start collecting report.
+2021-01-25 08:22:42.278 [CodeMars1] INFO . - Command: "D:\tools\DevEco Studio\plugins\codecheck\lib\CodeMars\engines\SecFinder-J\bin\run_SecFinder-J.bat",-filelist,E:\DecosCode\Test\.idea\code-check\java\filelist_2021_01_25_08_22_42_271_77.txt,-f,xml,-default,-progress,-r,E:\DecosCode\Test\.idea\code-check\java\\errorreport_2021_01_25_08_22_41_905_51.xml,-ruleclasspath,file:///E:\DecosCode\Test\.idea\code-check\java\ruleclasspath.txt
+2021-01-25 08:22:43.525 [Thread-2] INFO . - һ 25, 2021 8:22:43 com.huawei.secfinderj.SecFinderJ needScan
+2021-01-25 08:22:43.526 [Thread-2] INFO . - Ϣ: SecFinder-J Version: 2.1.3
+2021-01-25 08:22:43.647 [Thread-1] INFO . - 2021-01-25 08:22:43.603: SecFinder-J Output: Inspect start...
+2021-01-25 08:22:44.170 [Thread-1] INFO . - 2021-01-25 08:22:44.170: SecFinder-J Output: Load checkers...
+2021-01-25 08:22:44.630 [Thread-1] INFO . - 2021-01-25 08:22:44.630: SecFinder-J Output: Load config...
+2021-01-25 08:22:44.664 [Thread-1] INFO . - 2021-01-25 08:22:44.663: SecFinder-J Output: step 1/4: Find files
+2021-01-25 08:22:44.693 [Thread-1] INFO . - 2021-01-25 08:22:44.693: SecFinder-J Output: step 2/4: Process files
+2021-01-25 08:22:44.733 [Thread-1] INFO . - 2021-01-25 08:22:44.731: SecFinder-J Output: step 3/4: Run analysis...
+2021-01-25 08:22:45.030 [Thread-1] INFO . - 2021-01-25 08:22:45.030: SecFinder-J Output: step 4/4: Result output...
+2021-01-25 08:22:45.031 [Thread-1] INFO . - 2021-01-25 08:22:45.030: SecFinder-J Output: Inspect finish...
+2021-01-25 08:22:45.031 [Thread-1] INFO . - Analysis result:
+2021-01-25 08:22:45.031 [Thread-1] INFO . - files analyzed : 0
+2021-01-25 08:22:45.031 [Thread-1] INFO . - lines analyzed : 0
+2021-01-25 08:22:45.032 [Thread-1] INFO . - rules used : 59
+2021-01-25 08:22:45.032 [Thread-1] INFO . - issues detected : 0
+2021-01-25 08:22:45.032 [Thread-1] INFO . - time cost(sec) : 1
+2021-01-25 08:22:45.032 [Thread-1] INFO . -
+2021-01-25 08:22:45.032 [Thread-2] INFO . - һ 25, 2021 8:22:45 com.huawei.secfinderj.override.HwPmd end
+2021-01-25 08:22:45.032 [Thread-2] INFO . - Ϣ: SecFinder-J run successed!
+2021-01-25 08:22:45.673 [CodeMars1] INFO . - start parse errorreport xml
+2021-01-25 08:22:45.958 [CodeMars1] INFO . - parse xml time : 828
+2021-01-25 08:22:45.959 [CodeMars1] INFO . - end parse errorreport xml
+2021-01-25 08:22:45.961 [main] INFO . - end collecting report.
+2021-01-25 08:22:45.961 [main] INFO . - end analyzing.
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/detect.txt b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/detect.txt
new file mode 100644
index 0000000000000000000000000000000000000000..14d146469cce24b1da47e9f827086e4f37464858
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/detect.txt
@@ -0,0 +1 @@
+E:/DecosCode/Test/entry/src/main/java/com/huawei/test/view/CircleIndicatorComponent.java
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/output.xml b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/output.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4c5adbe1c6885668e3e01d7da1ad8cf2387dbf6b
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/output.xml
@@ -0,0 +1,9 @@
+
+
+
+
+0
+0
+1
+0
+
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/ruleclasspath.txt b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/ruleclasspath.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9dd9d74a8cdd68997700aebb20d3c918bf32b21f
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/code-check/java/ruleclasspath.txt
@@ -0,0 +1 @@
+D:\tools\DevEco Studio\plugins\codecheck\lib\CodeMars\engines\SecFinder-J\rule\
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/compiler.xml b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/gradle.xml b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d170aaeb1c8a392a01d7b10e38987bcd0552e251
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/jarRepositories.xml b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/misc.xml b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_349225176.json b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_349225176.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_349225176.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_493037853.json b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_493037853.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_493037853.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/previewConfig.json b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..0c62f55350656952d2b14d3668441cd5198e34e2
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,10 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "E:\\DecosCode\\Test\\entry": [],
+ "D:\\PCFile\\PCFile\\svn\\022.CircleIndicatorComponent\\CircleIndicatorComponent\\Test\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/tv/tvSettingConfig_349225176.json b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/tv/tvSettingConfig_349225176.json
new file mode 100644
index 0000000000000000000000000000000000000000..d0572715f06cf1e7c433f29cd68892def22dc903
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/tv/tvSettingConfig_349225176.json
@@ -0,0 +1,37 @@
+{
+ "setting": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "960*540"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "tv"
+ }
+ }
+ },
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "960*540"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "tv"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/tv/tvSettingConfig_493037853.json b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/tv/tvSettingConfig_493037853.json
new file mode 100644
index 0000000000000000000000000000000000000000..4b985169946e95a83c0c8c7d5ba18951f5e5ce61
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/.idea/previewer/tv/tvSettingConfig_493037853.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "960*540"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "tv"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git "a/019.CircleIndicatorComponent_OpenHarmony-master/019.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204CircleIndicatorComponent\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/019.CircleIndicatorComponent_OpenHarmony-master/019.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204CircleIndicatorComponent\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..29c3839c290cfd9f6c938fa6ddc57c3b91bd301b
Binary files /dev/null and "b/019.CircleIndicatorComponent_OpenHarmony-master/019.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204CircleIndicatorComponent\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/build.gradle b/019.CircleIndicatorComponent_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..55ee9133b112de29625c7bbc52be1caad80bdd5f
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/.gitignore b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/build.gradle b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/config.json b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb0dc00495b37aba7b8f3cbfea8126f7269fc497
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.huawei.test",
+ "vendor": "huawei",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.huawei.circleindicatorcomponent",
+ "deviceType": [
+ "tv"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "circleindicatorcomponent",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/java/com/huawei/circleindicatorcomponent/CircleIndicatorComponent.java b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/java/com/huawei/circleindicatorcomponent/CircleIndicatorComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..dfab88e62a9b4d0d9ba9dd284c2e672db44b281f
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/java/com/huawei/circleindicatorcomponent/CircleIndicatorComponent.java
@@ -0,0 +1,428 @@
+package com.huawei.circleindicatorcomponent;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.PageSlider;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.common.Rect;
+import ohos.multimodalinput.event.MmiPoint;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by zhouwei on 17/5/22.
+ */
+
+public class CircleIndicatorComponent extends Component implements PageSlider.PageChangedListener, Component.TouchEventListener {
+ private static final String LETTER[] = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
+ /**
+ * 选中控件胡默认颜色
+ */
+ private Color mSelectColor = Color.RED;
+ /**
+ * 画圆paint
+ */
+ private Paint mCirclePaint;
+ /**
+ * 字体画笔
+ */
+ private Paint mTextPaint;
+ /**
+ * indicator 的数量
+ */
+ private int mCount = 0;
+ /**
+ * 半径
+ */
+ private int mRadius;
+ /**
+ * 画笔粗细
+ */
+ private int mStrokeWidth;
+ /**
+ * 小圆点中文字的颜色
+ */
+ private Color mTextColor;
+ /**
+ * 小圆点默认颜色
+ */
+ private Color mDotNormalColor;
+ /**
+ * 圆点之间的间距
+ */
+ private int mSpace = 0;
+ /**
+ * 指示器胡集合
+ */
+ public List mIndicators = new ArrayList<>();
+ /**
+ * 选中的位置
+ */
+ private int mSelectPosition = 0;
+ /**
+ * 默认只有小圆点
+ */
+ private FillMode mFillMode = FillMode.NONE;
+ /**
+ * page组件
+ */
+ private PageSlider mViewPager;
+ /**
+ * 指示器监听
+ */
+ private OnIndicatorClickListener mOnIndicatorClickListener;
+ /**
+ * 是否允许点击Indicator切换ViewPager
+ */
+ private boolean mIsEnableClickSwitch = true;
+ /**
+ * fill_mode
+ */
+ private int fillMode=0;
+ /**
+ * 绘画的task
+ */
+ public DrawTask taskVis = new DrawTask() {
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ for (int i = 0; i < mIndicators.size(); i++) {
+ Indicator indicator = mIndicators.get(i);
+ float x = indicator.cx;//x坐标
+ float y = indicator.cy;//y坐标
+ if (mSelectPosition == i) {
+ mCirclePaint.setStyle(Paint.Style.FILL_STYLE);
+ mCirclePaint.setColor(mSelectColor);
+ } else {
+ mCirclePaint.setColor(mDotNormalColor);
+ if (mFillMode != FillMode.NONE) {
+ mCirclePaint.setStyle(Paint.Style.FILL_STYLE);
+ } else {
+ mCirclePaint.setStyle(Paint.Style.STROKE_STYLE);
+ }
+ }
+ canvas.drawCircle(x, 300, mRadius, mCirclePaint);
+ // 绘制小圆点中的内容
+ if (mFillMode != FillMode.NONE) {
+ String text = "";
+ if (mFillMode == FillMode.LETTER) {
+ if (i >= 0 && i < LETTER.length) {
+ text = LETTER[i];
+ }
+ } else {
+ text = String.valueOf(i + 1);
+ }
+ Rect bound = new Rect();
+ mTextPaint.getTextBounds(text);
+ int textWidth = bound.width;
+ int textHeight = bound.height;
+ float textStartX = x - textWidth / 2;
+ float textStartY = y + textHeight / 2;
+ canvas.drawText(mTextPaint, text, 0, 0);
+ }
+
+ }
+
+ }
+ };
+
+ public CircleIndicatorComponent(Context context) {
+ super(context);
+ this.mContext = context;
+ }
+
+ public CircleIndicatorComponent(Context context, AttrSet attrs) {
+ super(context, attrs);
+ getAttr(context, attrs);
+ }
+
+ public CircleIndicatorComponent(Context context, AttrSet attrs, String defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ getAttr(context, attrs);
+
+ }
+
+ public CircleIndicatorComponent(Context context, AttrSet attrSet, int resId) {
+ super(context, attrSet, resId);
+ getAttr(context, attrSet);
+ }
+
+ private void init() {
+ mCirclePaint = new Paint();
+ mCirclePaint.setDither(true);
+ mCirclePaint.setAntiAlias(true);
+ mCirclePaint.setStyle(Paint.Style.FILL_STYLE);
+
+ mTextPaint = new Paint();
+ mTextPaint.setDither(true);
+ mTextPaint.setAntiAlias(true);
+ // 默认值
+ mIndicators = new ArrayList<>();
+ initValue();
+ addDrawTask(taskVis);
+ }
+
+ private void initValue() {
+ mCirclePaint.setColor(mDotNormalColor);
+ mCirclePaint.setStrokeWidth(mStrokeWidth);
+
+ mTextPaint.setColor(mTextColor);
+ mTextPaint.setTextSize(mRadius);
+ }
+
+ /**
+ * 获取自定义属性
+ *
+ * @param context
+ * @param attrs
+ */
+ private void getAttr(Context context, AttrSet attrs) {
+ mRadius = attrs.getAttr("indicatorRadius").get().getIntegerValue();
+ mStrokeWidth = attrs.getAttr("indicatorBorderWidth").get().getIntegerValue();
+ mSpace = attrs.getAttr("indicatorSpace").get().getDimensionValue();
+ // color
+ mTextColor = attrs.getAttr("indicatorTextColor").get().getColorValue();
+ mSelectColor = attrs.getAttr("indicatorSelectColor").get().getColorValue();
+ mDotNormalColor = attrs.getAttr("indicatorColor").get().getColorValue();
+
+ mIsEnableClickSwitch = attrs.getAttr("enableIndicatorSwitch").get().getBoolValue();
+ fillMode = attrs.getAttr("fill_mode").get().getIntegerValue();
+
+ if (fillMode == 1) {
+ mFillMode = FillMode.LETTER;
+ } else if (fillMode == 1) {
+ mFillMode = FillMode.NUMBER;
+ } else {
+ mFillMode = FillMode.NONE;
+ }
+ init();
+ }
+
+ /**
+ * 测量每个圆点的位置
+ */
+ private void measureIndicator(int count) {
+ mIndicators.clear();
+ float cx = 0;
+ for (int i = 0; i < count; i++) {
+ HiLog.error(new HiLogLabel(HiLog.LOG_APP, 1212, "rrrrrrr"), mCount + "");
+ Indicator indicator = new Indicator();
+ if (i == 0) {
+ cx = mRadius + mStrokeWidth;
+ } else {
+ cx += (mRadius + mStrokeWidth) * 2 + mSpace;
+ }
+ indicator.cx = cx;
+ indicator.cy = 0;
+ mIndicators.add(indicator);
+ }
+ }
+
+
+ @Override
+ public void addDrawTask(DrawTask task) {
+ super.addDrawTask(task);
+ task.onDraw(this, mCanvasForTaskOverContent);
+ }
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ float xPoint = 0;
+ float yPoint = 0;
+ switch (touchEvent.getAction()) {
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ MmiPoint event = touchEvent.getPointerScreenPosition(touchEvent.getIndex());
+ xPoint = event.getX();
+ yPoint = event.getY();
+ handleActionDown(xPoint, yPoint);
+ break;
+ }
+ return true;
+ }
+
+
+ private void handleActionDown(float xDis, float yDis) {
+ for (int i = 0; i < mCount; i++) {
+ Indicator indicator = mIndicators.get(i);
+ if (xDis < (indicator.cx + mRadius + mStrokeWidth)
+ && xDis >= (indicator.cx - (mRadius + mStrokeWidth))
+ && yDis >= (yDis - (indicator.cy + mStrokeWidth))
+ && yDis < (indicator.cy + mRadius + mStrokeWidth)) {
+ // 找到了点击的Indicator
+ // 是否允许切换ViewPager
+ if (mIsEnableClickSwitch) {
+ int finalI = i;
+ mContext.getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mViewPager.setCurrentPage(finalI, false);
+ }
+ });
+
+ }
+
+ // 回调
+ if (mOnIndicatorClickListener != null) {
+ mOnIndicatorClickListener.onSelected(i);
+ }
+ break;
+ }
+ }
+ }
+
+ public void setOnIndicatorClickListener(OnIndicatorClickListener onIndicatorClickListener) {
+ mOnIndicatorClickListener = onIndicatorClickListener;
+ }
+
+ private void setCount(int count) {
+ mCount = count;
+ HiLog.error(new HiLogLabel(HiLog.LOG_APP,10012 , "CircleIndicatorComponent"), mCount + "");
+ invalidate();
+ }
+
+ /**
+ * 设置 border
+ *
+ * @param borderWidth
+ */
+ public void setBorderWidth(int borderWidth) {
+ mStrokeWidth = borderWidth;
+ invalidate();
+ }
+
+ /**
+ * 设置文字的颜色
+ *
+ * @param textColor
+ */
+ public void setTextColor(Color textColor) {
+ mTextColor = textColor;
+ invalidate();
+ }
+
+ /**
+ * 设置选中指示器的颜色
+ *
+ * @param selectColor
+ */
+ public void setSelectColor(Color selectColor) {
+ mSelectColor = selectColor;
+ }
+
+ /**
+ * 设置指示器默认颜色
+ *
+ * @param dotNormalColor
+ */
+ public void setDotNormalColor(Color dotNormalColor) {
+ mDotNormalColor = dotNormalColor;
+ invalidate();
+ }
+
+ /**
+ * 设置选中的位置
+ *
+ * @param selectPosition
+ */
+ public void setSelectPosition(int selectPosition) {
+ mSelectPosition = selectPosition;
+ }
+
+ /**
+ * 设置Indicator 模式
+ *
+ * @param fillMode
+ */
+ public void setFillMode(FillMode fillMode) {
+ mFillMode = fillMode;
+ }
+
+ /**
+ * 设置Indicator 半径
+ *
+ * @param radius
+ */
+ public void setRadius(int radius) {
+ mRadius = radius;
+ }
+
+ public void setSpace(int space) {
+ mSpace = space;
+ }
+
+ public void setEnableClickSwitch(boolean enableClickSwitch) {
+ mIsEnableClickSwitch = enableClickSwitch;
+ }
+
+ /**
+ * 与ViewPager 关联
+ *
+ * @param viewPager
+ */
+ public void setUpWithViewPager(PageSlider viewPager) {
+
+ if (viewPager == null) {
+ return;
+ }
+ int count = viewPager.getProvider().getCount();
+ measureIndicator(count);
+ this.mViewPager = viewPager;
+ mViewPager.addPageChangedListener(this);
+ setCount(count);
+ }
+
+ /**
+ * 重置ViewPager
+ */
+ private void releaseViewPager() {
+ if (mViewPager != null) {
+ mViewPager.removePageChangedListener(this);
+ mViewPager = null;
+ }
+
+ }
+
+ @Override
+ public void onPageSliding(int i, float v, int i1) {
+
+ }
+
+ @Override
+ public void onPageSlideStateChanged(int i) {
+
+ }
+
+ @Override
+ public void onPageChosen(int i) {
+ mSelectPosition = i;
+ invalidate();
+ }
+
+
+ /**
+ * Indicator 点击回调
+ */
+ public interface OnIndicatorClickListener {
+ public void onSelected(int position);
+ }
+
+
+ public static class Indicator {
+ public float cx; // 圆心x坐标
+ public float cy; // 圆心y 坐标
+ }
+
+ public enum FillMode {
+ LETTER,
+ NUMBER,
+ NONE
+ }
+
+
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/resources/base/element/string.json b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..45faa37a2d71a0087d84d91dc508f945e600c281
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/circleindicatorcomponent/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "CircleIndicatorComponent"
+ }
+ ]
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/.gitignore b/019.CircleIndicatorComponent_OpenHarmony-master/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/build.gradle b/019.CircleIndicatorComponent_OpenHarmony-master/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..fcce9d699ddf6271d6f977dff029db05bf33e517
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ implementation(project(':circleindicatorcomponent'))
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/config.json b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..3e326cda86a7f32ee6372711b689f892c876403f
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/config.json
@@ -0,0 +1,50 @@
+{
+ "app": {
+ "bundleName": "com.huawei.test",
+ "vendor": "huawei",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.huawei.test",
+ "name": ".MyApplication",
+ "deviceType": [
+ "tv",
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "portrait",
+ "name": "com.huawei.test.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_label",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/MainAbility.java b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..edfb3cb862ca22b2681209947b89086b2be30883
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/MainAbility.java
@@ -0,0 +1,13 @@
+package com.huawei.test;
+
+import com.huawei.test.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/MyApplication.java b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..46d24825a2b922fc1dfcc34e974aba7ca8c8f0c6
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/MyApplication.java
@@ -0,0 +1,10 @@
+package com.huawei.test;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/slice/MainAbilitySlice.java b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..12ae2255b25218b4f7a5727ae6acee02ecf3ffe8
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/slice/MainAbilitySlice.java
@@ -0,0 +1,64 @@
+package com.huawei.test.slice;
+
+import com.huawei.circleindicatorcomponent.CircleIndicatorComponent;
+import com.huawei.test.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.PageSlider;
+import ohos.agp.utils.Color;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class MainAbilitySlice extends AbilitySlice {
+ private ViewPagerAdapter adapter;
+ private PageSlider pageSlider;
+ private CircleIndicatorComponent mIndicatorView;
+ private static final int[] RES = new int[]{com.huawei.test.ResourceTable.Media_image1,
+ com.huawei.test.ResourceTable.Media_image2,
+ com.huawei.test.ResourceTable.Media_image3,
+ com.huawei.test.ResourceTable.Media_image4};
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ // 初始化ViewPager 相关
+ pageSlider = (PageSlider) findComponentById(ResourceTable.Id_viewpager);
+ adapter = new ViewPagerAdapter(this, RES);
+ mIndicatorView = (CircleIndicatorComponent) findComponentById(ResourceTable.Id_indicator_view1);
+ // 设置半径
+ mIndicatorView.setRadius(50);
+ // 设置Border
+ mIndicatorView.setBorderWidth(30);
+ // 设置文字颜色
+ mIndicatorView.setTextColor(Color.BLACK);
+ // 设置选中颜色
+ mIndicatorView.setSelectColor(Color.GREEN);
+ //未选中状态
+ mIndicatorView.setDotNormalColor(Color.RED);
+ // pageslider绑定数据
+ pageSlider.setProvider(adapter);
+ // 最重要的一步:关联ViewPager
+ mIndicatorView.setUpWithViewPager(pageSlider);
+ mIndicatorView.setOnIndicatorClickListener(new CircleIndicatorComponent.OnIndicatorClickListener() {
+ @Override
+ public void onSelected(int position) {
+
+
+
+ }
+ });
+
+ }
+
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/slice/ViewPagerAdapter.java b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/slice/ViewPagerAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9f671808d3f102c2700b41b87f50ba6a116057a
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/java/com/huawei/test/slice/ViewPagerAdapter.java
@@ -0,0 +1,45 @@
+package com.huawei.test.slice;
+
+import ohos.agp.components.*;
+import ohos.app.Context;
+import ohos.global.resource.Resource;
+import ohos.global.systemres.ResourceTable;
+
+import java.util.List;
+
+/**
+ * Created by zhouwei on 17/5/22.
+ */
+
+public class ViewPagerAdapter extends PageSliderProvider {
+ private Context mContext;
+ private int[] RES;
+ public ViewPagerAdapter(Context context, int[] RES) {
+ mContext = context;
+ this.RES = RES;
+ }
+ @Override
+ public int getCount() {
+ return RES.length;
+ }
+
+ @Override
+ public Object createPageInContainer(ComponentContainer componentContainer, int i) {
+ Component view = LayoutScatter.getInstance(mContext).parse(com.huawei.test.ResourceTable.Layout_view_pager_item,null,false);
+ Image imageView = (Image) view.findComponentById(com.huawei.test.ResourceTable.Id_item_image);
+ imageView.setPixelMap(RES[i]);
+ componentContainer.addComponent(view);
+ return view;
+ }
+
+ @Override
+ public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
+ componentContainer.removeComponent((Component) o);
+
+ }
+
+ @Override
+ public boolean isPageMatchToObject(Component component, Object o) {
+ return component == o;
+ }
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/element/string.json b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..6445513c67ee2bfdb5f3bce2ba1f0ba54f5f0b0f
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,25 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Test"
+ },
+
+ {
+ "name": "app_label",
+ "value": "Test"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_TV_Empty Feature Ability"
+ },
+ {
+ "name": "serviceability_description",
+ "value": "hap sample empty service"
+ },
+ {
+ "name": "dataability_description",
+ "value": "hap sample empty provider"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4348419273d05ec3f20066249d948bbedd670a9d
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/layout/view_pager_item.xml b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/layout/view_pager_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fce829187e1bb34a2dfbca4b7fbe4028fe81fb1a
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/layout/view_pager_item.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/icon.png b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/icon.png differ
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image1.jpg b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e882bd76af000e6b5a5ef4244a0357aa3c9d58ad
Binary files /dev/null and b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image1.jpg differ
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image2.jpeg b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image2.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..a3b5ffae959dedefbf417e4c01ee5f028a28998f
Binary files /dev/null and b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image2.jpeg differ
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image3.jpeg b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image3.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..d2a7e44f4b6c4805c6229cd055b6295cb2dbb153
Binary files /dev/null and b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image3.jpeg differ
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image4.jpeg b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image4.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..812987b6900456368e212aa422301d7588ee934a
Binary files /dev/null and b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/main/resources/base/media/image4.jpeg differ
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/test/java/com/huawei/test/ExampleTest.java b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/test/java/com/huawei/test/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae0dbd8526d07d5c4cb89a9731fde0f8991cd0ff
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/entry/src/test/java/com/huawei/test/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.huawei.test;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/gradle.properties b/019.CircleIndicatorComponent_OpenHarmony-master/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar b/019.CircleIndicatorComponent_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/019.CircleIndicatorComponent_OpenHarmony-master/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties b/019.CircleIndicatorComponent_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/gradlew b/019.CircleIndicatorComponent_OpenHarmony-master/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/gradlew.bat b/019.CircleIndicatorComponent_OpenHarmony-master/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/019.CircleIndicatorComponent_OpenHarmony-master/settings.gradle b/019.CircleIndicatorComponent_OpenHarmony-master/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..e1fb26e1e1c112589c2195cad72837f786c260d7
--- /dev/null
+++ b/019.CircleIndicatorComponent_OpenHarmony-master/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':circleindicatorcomponent'
diff --git a/020.Cropper_OpenHarmony-master/cropper/.gitignore b/020.Cropper_OpenHarmony-master/cropper/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/020.Cropper_OpenHarmony-master/cropper/.idea/.gitignore b/020.Cropper_OpenHarmony-master/cropper/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/020.Cropper_OpenHarmony-master/cropper/.idea/compiler.xml b/020.Cropper_OpenHarmony-master/cropper/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/.idea/gradle.xml b/020.Cropper_OpenHarmony-master/cropper/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d5c3920b02a5f1a67868da53099818eea340a8c1
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/.idea/jarRepositories.xml b/020.Cropper_OpenHarmony-master/cropper/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/.idea/misc.xml b/020.Cropper_OpenHarmony-master/cropper/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..58918f50335428f2efb3af4d621f9f405ed659d4
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/.idea/previewer/phone/phoneSettingConfig_-301689984.json b/020.Cropper_OpenHarmony-master/cropper/.idea/previewer/phone/phoneSettingConfig_-301689984.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.idea/previewer/phone/phoneSettingConfig_-301689984.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/.idea/previewer/previewConfig.json b/020.Cropper_OpenHarmony-master/cropper/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..41489982558dfc34ff314b6b9eda7cc935f26aa3
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/.idea/previewer/previewConfig.json
@@ -0,0 +1,9 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\PCFile\\PCFile\\svn\\023.Cropper\\cropper\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git "a/020.Cropper_OpenHarmony-master/cropper/020.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204cropper\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/020.Cropper_OpenHarmony-master/cropper/020.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204cropper\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..044d060d8ce7cfe97b277f38c6bbb6e26eec1ee5
Binary files /dev/null and "b/020.Cropper_OpenHarmony-master/cropper/020.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204cropper\344\270\211\346\226\271\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/build.gradle b/020.Cropper_OpenHarmony-master/cropper/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0da9bc913f7350fad9087d8535f200bedce92ed3
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib-debug.har b/020.Cropper_OpenHarmony-master/cropper/cropperlib-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..1eb56c9376d675b5bcbf8081acfa60a4908712d4
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/cropperlib-debug.har differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/.gitignore b/020.Cropper_OpenHarmony-master/cropper/cropperlib/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/build.gradle b/020.Cropper_OpenHarmony-master/cropper/cropperlib/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/config.json b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..c08679e157aab2aa7faae20c05a9f27285fd2c63
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.cropper",
+ "vendor": "crop",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.crop.cropperlib",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "cropperlib",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/CropImage.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/CropImage.java
new file mode 100644
index 0000000000000000000000000000000000000000..5fa232926f5c0a701fb9a15f3c0c9a3e497081cf
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/CropImage.java
@@ -0,0 +1,263 @@
+package com.crop.cropperlib;
+
+import com.crop.cropperlib.border.Frame;
+import com.crop.cropperlib.handle.Handle;
+import com.crop.cropperlib.utils.HandleUtil;
+import com.crop.cropperlib.utils.PaintUtil;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.render.Canvas;
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Point;
+import ohos.agp.utils.RectFloat;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.PixelMap;
+import ohos.media.image.common.Rect;
+import ohos.media.image.common.Size;
+import ohos.multimodalinput.event.MmiPoint;
+import ohos.multimodalinput.event.TouchEvent;
+
+public class CropImage extends Image implements Component.TouchEventListener, Component.DrawTask,
+ Component.LayoutRefreshedListener {
+ private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00202, "CROP");
+
+ // 手柄周围可触摸区域的半径(以像素为单位)。
+ // 我们是基于建议的48dp触摸目标大小的值
+ private static final float M_HANDLE_RADIUS = 24f;
+
+ // 当裁剪窗口边缘与边界框边缘的距离小于或等于此距离(以像素为单位)时,裁剪窗口的边缘将捕捉到指定边界框的相应边缘
+ private static final float M_SNAP_RADIUS = 3f;
+
+ // 用来在裁剪区域周围绘制白色矩形
+ private Paint mBorderPaint;
+
+ // 按下时用于在裁剪区域内绘制指导线
+ private Paint mGuidelinePaint;
+
+ // 用于使特定区域以外变暗
+ private Paint mSurroundingAreaPaint;
+
+ // 正在裁剪的位图周围的边界框
+ private RectFloat mPixelMapRect = new RectFloat();
+
+ // 保持精确触摸位置和激活的精确手柄位置之间的x和y偏移。
+ // 可能有一个偏移量,因为我们在激活句柄时允许一些余地(由“mHandleRadius”指定)。
+ // 但是,我们希望在拖动控制柄时保持这些偏移值,以便控制柄不会跳转。
+ private Point mTouchOffset = new Point();
+
+ // 当前按下的句柄;如果没有按下句柄,则为空。
+ private Handle mPressedHandle;
+
+ // 组件左上角X坐标
+ private int topLeftX;
+
+ // 组件左上角Y坐标
+ private int topLeftY;
+
+ public CropImage(Context context) {
+ super(context);
+ init();
+ }
+
+ public CropImage(Context context, AttrSet attrSet) {
+ super(context, attrSet);
+ init();
+ }
+
+ public CropImage(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ init();
+ }
+
+ private void init() {
+ mBorderPaint = PaintUtil.getBorderPaint();
+ mGuidelinePaint = PaintUtil.getGuidelinePaint();
+ mSurroundingAreaPaint = PaintUtil.getSurroundingAreaPaint();
+ setLayoutRefreshedListener(this);
+ addDrawTask(this);
+ setTouchEventListener(this);
+ }
+
+ private void initCropWindow() {
+ ohos.agp.utils.Rect position = getComponentPosition();
+ topLeftX = position.getCenterX() - getWidth() / 2;
+ topLeftY = position.getCenterY() - getHeight() / 2;
+ mPixelMapRect = getPixelMapRect();
+ // 初始化裁剪窗口,使其具有相对于可绘制边界的10%填充
+ float horizontalPadding = 0.1f * mPixelMapRect.getWidth();
+ float verticalPadding = 0.1f * mPixelMapRect.getHeight();
+ Frame.LEFT.setCoordinate(mPixelMapRect.left + horizontalPadding);
+ Frame.TOP.setCoordinate(mPixelMapRect.top + verticalPadding);
+ Frame.RIGHT.setCoordinate(mPixelMapRect.right - horizontalPadding);
+ Frame.BOTTOM.setCoordinate(mPixelMapRect.bottom - verticalPadding);
+ }
+
+ @Override
+ public void onRefreshed(Component component) {
+ initCropWindow();
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ drawDarkenedSurroundingArea(canvas);
+ drawGuidelines(canvas);
+ drawBorder(canvas);
+ }
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ switch (touchEvent.getAction()) {
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ MmiPoint point1 = touchEvent.getPointerPosition(touchEvent.getIndex());
+ onActionDown(point1.getX() - topLeftX, point1.getY() - topLeftY);
+ invalidate();
+ return true;
+ case TouchEvent.PRIMARY_POINT_UP:
+ case TouchEvent.CANCEL:
+ onActionUp();
+ invalidate();
+ return true;
+ case TouchEvent.POINT_MOVE:
+ MmiPoint point2 = touchEvent.getPointerPosition(touchEvent.getIndex());
+ onActionMove(point2.getX() - topLeftX, point2.getY() - topLeftY);
+ invalidate();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public PixelMap getCroppedImage() {
+ float scaleX = getScaleX();
+ float scaleY = getScaleY();
+ float transX = getTranslationX();
+ float transY = getTranslationY();
+
+ float pixelMapLeft = (transX < 0) ? Math.abs(transX) : 0;
+ float pixelMapTop = (transY < 0) ? Math.abs(transY) : 0;
+
+ float cropX = (pixelMapLeft + Frame.LEFT.getCoordinate()) / scaleX;
+ float cropY = (pixelMapTop + Frame.TOP.getCoordinate()) / scaleY;
+
+ PixelMap originalPixelMap = this.getPixelMap();
+ Size size = originalPixelMap.getImageInfo().size;
+
+ float hideX = 0f;
+ if (size.width > getWidth()) {
+ hideX = (size.width - getWidth()) / 2f;
+ }
+ float hideY = 0f;
+ if (size.height > getHeight()) {
+ hideY = (size.height - getHeight()) / 2f;
+ }
+
+ float cropWidth = Math.min(Frame.getWidth() / scaleX, size.width - cropX);
+ float cropHeight = Math.min(Frame.getHeight() / scaleY, size.height - cropY);
+
+ Rect cropRect = new Rect((int)(cropX + hideX), (int)(cropY + hideY),(int)cropWidth, (int)cropHeight);
+ PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
+ options.size = new Size(cropRect.width, cropRect.height);
+ return PixelMap.create(originalPixelMap, cropRect, options);
+ }
+
+ private RectFloat getPixelMapRect() {
+ float scaleX = getScaleX();
+ float scaleY = getScaleY();
+ float transX = getTranslationX();
+ float transY = getTranslationY();
+
+ PixelMap originalPixelMap = this.getPixelMap();
+ Size size = originalPixelMap.getImageInfo().size;
+
+ int drawableDisplayWidth = Math.round(size.width * scaleX);
+ int drawableDisplayHeight = Math.round(size.height * scaleY);
+
+ float left = Math.max(transX, 0);
+ float top = Math.max(transY, 0);
+ float right = Math.min(left + drawableDisplayWidth, getWidth());
+ float bottom = Math.min(top + drawableDisplayHeight, getHeight());
+
+ return new RectFloat(left, top, right, bottom);
+ }
+
+ private void drawDarkenedSurroundingArea(Canvas canvas) {
+ RectFloat bitmapRect = mPixelMapRect;
+ float left = Frame.LEFT.getCoordinate();
+ float top = Frame.TOP.getCoordinate();
+ float right = Frame.RIGHT.getCoordinate();
+ float bottom = Frame.BOTTOM.getCoordinate();
+
+ RectFloat rect = new RectFloat(bitmapRect.left, bitmapRect.top, bitmapRect.right, top);
+ canvas.drawRect(rect, mSurroundingAreaPaint);
+
+ rect = new RectFloat(bitmapRect.left, bottom, bitmapRect.right, bitmapRect.bottom);
+ canvas.drawRect(rect, mSurroundingAreaPaint);
+
+ rect = new RectFloat(bitmapRect.left, top, left, bottom);
+ canvas.drawRect(rect, mSurroundingAreaPaint);
+
+ rect = new RectFloat(right, top, bitmapRect.right, bottom);
+ canvas.drawRect(rect, mSurroundingAreaPaint);
+ }
+
+ private void drawGuidelines(Canvas canvas) {
+ float left = Frame.LEFT.getCoordinate();
+ float top = Frame.TOP.getCoordinate();
+ float right = Frame.RIGHT.getCoordinate();
+ float bottom = Frame.BOTTOM.getCoordinate();
+
+ // 绘制垂直线
+ float oneThirdCropWidth = Frame.getWidth() / 3;
+
+ float x1 = left + oneThirdCropWidth;
+ canvas.drawLine(new Point(x1, top), new Point(x1, bottom), mGuidelinePaint);
+ float x2 = right - oneThirdCropWidth;
+ canvas.drawLine(new Point(x2, top), new Point(x2, bottom), mGuidelinePaint);
+
+ // 画水平线
+ float oneThirdCropHeight = Frame.getHeight() / 3;
+
+ float y1 = top + oneThirdCropHeight;
+ canvas.drawLine(new Point(left, y1), new Point(right, y1), mGuidelinePaint);
+
+ float y2 = bottom - oneThirdCropHeight;
+ canvas.drawLine(new Point(left, y2), new Point(right, y2), mGuidelinePaint);
+ }
+
+ private void drawBorder(Canvas canvas) {
+ RectFloat rect = new RectFloat(
+ Frame.LEFT.getCoordinate(),
+ Frame.TOP.getCoordinate(),
+ Frame.RIGHT.getCoordinate(),
+ Frame.BOTTOM.getCoordinate());
+ canvas.drawRect(rect, mBorderPaint);
+ }
+
+ private void onActionDown(float x, float y) {
+ float left = Frame.LEFT.getCoordinate();
+ float top = Frame.TOP.getCoordinate();
+ float right = Frame.RIGHT.getCoordinate();
+ float bottom = Frame.BOTTOM.getCoordinate();
+ mPressedHandle = HandleUtil.getPressedHandle(x, y, left, top, right, bottom, M_HANDLE_RADIUS);
+ HandleUtil.getOffset(mPressedHandle, x, y, left, top, right, bottom, mTouchOffset);
+
+ }
+
+ private void onActionUp() {
+ if (mPressedHandle != null) {
+ mPressedHandle = null;
+ }
+ }
+
+ private void onActionMove(float x, float y) {
+ if (mPressedHandle == null) {
+ return;
+ }
+ x += mTouchOffset.getPointX();
+ y += mTouchOffset.getPointY();
+ mPressedHandle.refreshCropWindow(x, y, mPixelMapRect, M_SNAP_RADIUS);
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/border/Frame.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/border/Frame.java
new file mode 100644
index 0000000000000000000000000000000000000000..53b852c569678fe5554be0fa9436b9e5bd955d0a
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/border/Frame.java
@@ -0,0 +1,424 @@
+package com.crop.cropperlib.border;
+
+import com.crop.cropperlib.utils.AspectRatioUtil;
+import ohos.agp.utils.RectFloat;
+
+/**
+ * 表示裁剪窗口中的边的枚举
+ */
+public enum Frame {
+
+ LEFT,
+ TOP,
+ RIGHT,
+ BOTTOM;
+
+ // 一条边到另一条边的最小距离
+ // 这是一个任意值,可以简单地防止裁剪窗口变得太小
+ public static final int MIN_CROP_LENGTH_PX = 40;
+
+ // 此边的坐标值.
+ // 这将是左右边缘的x坐标,以及上边缘和下边缘的y坐标
+ private float mCoordinate;
+
+ /**
+ * 设置框架的坐标。该坐标将表示左、右边缘的x坐标,以及上、下边缘的y坐标
+ *
+ * @param coordinate 边缘的位置
+ */
+ public void setCoordinate(float coordinate) {
+ mCoordinate = coordinate;
+ }
+
+ /**
+ * 将给定数量的像素添加到此帧的当前坐标位置
+ *
+ * @param distance 要添加的像素数
+ */
+ public void offset(float distance) {
+ mCoordinate += distance;
+ }
+
+ /**
+ * 获取边的坐标
+ *
+ * @return 边缘坐标(左右边缘的x坐标和上下边缘的y坐标)
+ */
+ public float getCoordinate() {
+ return mCoordinate;
+ }
+
+ /**
+ * 将边设置为给定的x-y坐标,但也调整为捕捉到图像边界和父视图边界约束
+ *
+ * @param x x坐标
+ * @param y y坐标
+ * @param imageRect 图像的边框
+ * @param imageSnapRadius 边缘应捕捉到图像的半径
+ */
+ public void adjustCoordinate(float x, float y, RectFloat imageRect, float imageSnapRadius, float aspectRatio) {
+ switch (this) {
+ case LEFT:
+ mCoordinate = adjustLeft(x, imageRect, imageSnapRadius, aspectRatio);
+ break;
+ case TOP:
+ mCoordinate = adjustTop(y, imageRect, imageSnapRadius, aspectRatio);
+ break;
+ case RIGHT:
+ mCoordinate = adjustRight(x, imageRect, imageSnapRadius, aspectRatio);
+ break;
+ case BOTTOM:
+ mCoordinate = adjustBottom(y, imageRect, imageSnapRadius, aspectRatio);
+ break;
+ }
+ }
+
+ /**
+ * 调整此帧位置,使生成的窗口具有给定的纵横比。
+ *
+ * @param aspectRatio 要达到的纵横比
+ */
+ public void adjustCoordinate(float aspectRatio) {
+ float left = Frame.LEFT.getCoordinate();
+ float top = Frame.TOP.getCoordinate();
+ float right = Frame.RIGHT.getCoordinate();
+ float bottom = Frame.BOTTOM.getCoordinate();
+
+ switch (this) {
+ case LEFT:
+ mCoordinate = AspectRatioUtil.calculateLeft(top, right, bottom, aspectRatio);
+ break;
+ case TOP:
+ mCoordinate = AspectRatioUtil.calculateTop(left, right, bottom, aspectRatio);
+ break;
+ case RIGHT:
+ mCoordinate = AspectRatioUtil.calculateRight(left, top, bottom, aspectRatio);
+ break;
+ case BOTTOM:
+ mCoordinate = AspectRatioUtil.calculateBottom(left, top, right, aspectRatio);
+ break;
+ }
+ }
+
+ /**
+ * 将此帧捕捉到给定的图像边界
+ *
+ * @param imageRect 要捕捉到的图像的边框
+ *
+ * @return 此坐标的更改量(以像素为单位)(即新坐标减去旧坐标值)
+ */
+ public float snapToRect(RectFloat imageRect) {
+ float oldCoordinate = mCoordinate;
+ switch (this) {
+ case LEFT:
+ mCoordinate = imageRect.left;
+ break;
+ case TOP:
+ mCoordinate = imageRect.top;
+ break;
+ case RIGHT:
+ mCoordinate = imageRect.right;
+ break;
+ case BOTTOM:
+ mCoordinate = imageRect.bottom;
+ break;
+ }
+ return mCoordinate - oldCoordinate;
+ }
+
+ /**
+ * 返回snapToRect的潜在捕捉偏移,而不更改坐标。
+ *
+ * @param imageRect 要捕捉到的图像的边框
+ *
+ *@return 此坐标更改的量(以像素为单位)(即新坐标减去旧坐标值)
+ */
+ public float snapOffset(RectFloat imageRect) {
+ float oldCoordinate = mCoordinate;
+ float newCoordinate;
+
+ switch (this) {
+ case LEFT:
+ newCoordinate = imageRect.left;
+ break;
+ case TOP:
+ newCoordinate = imageRect.top;
+ break;
+ case RIGHT:
+ newCoordinate = imageRect.right;
+ break;
+ default: // BOTTOM
+ newCoordinate = imageRect.bottom;
+ break;
+ }
+ return newCoordinate - oldCoordinate;
+ }
+
+ /**
+ * 获取裁剪窗口的当前宽度
+ */
+ public static float getWidth() {
+ return Frame.RIGHT.getCoordinate() - Frame.LEFT.getCoordinate();
+ }
+
+ /**
+ * 获取裁剪窗口的当前高度
+ */
+ public static float getHeight() {
+ return Frame.BOTTOM.getCoordinate() - Frame.TOP.getCoordinate();
+ }
+
+
+ /**
+ * 返回是否可以根据边缘是否超出边界来重新缩放图像。检查所有边缘是否有跳出边界的可能。
+ *
+ * @param frame 即将扩展的边缘
+ * @param imageRect 图片的矩形
+ * @param aspectRatio 图片所需的侧面
+ *
+ * @return 新图像是否超出范围.
+ */
+ public boolean isNewRectangleOutOfBounds(Frame frame, RectFloat imageRect, float aspectRatio) {
+ float offset = frame.snapOffset(imageRect);
+
+ switch (this) {
+ case LEFT:
+ if (frame.equals(Frame.TOP)) {
+ float top = imageRect.top;
+ float bottom = Frame.BOTTOM.getCoordinate() - offset;
+ float right = Frame.RIGHT.getCoordinate();
+ float left = AspectRatioUtil.calculateLeft(top, right, bottom, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ } else if (frame.equals(Frame.BOTTOM)) {
+ float bottom = imageRect.bottom;
+ float top = Frame.TOP.getCoordinate() - offset;
+ float right = Frame.RIGHT.getCoordinate();
+ float left = AspectRatioUtil.calculateLeft(top, right, bottom, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ }
+ break;
+ case TOP:
+ if (frame.equals(Frame.LEFT)) {
+ float left = imageRect.left;
+ float right = Frame.RIGHT.getCoordinate() - offset;
+ float bottom = Frame.BOTTOM.getCoordinate();
+ float top = AspectRatioUtil.calculateTop(left, right, bottom, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ } else if (frame.equals(Frame.RIGHT)) {
+ float right = imageRect.right;
+ float left = Frame.LEFT.getCoordinate() - offset;
+ float bottom = Frame.BOTTOM.getCoordinate();
+ float top = AspectRatioUtil.calculateTop(left, right, bottom, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ }
+ break;
+ case RIGHT:
+ if (frame.equals(Frame.TOP)) {
+ float top = imageRect.top;
+ float bottom = Frame.BOTTOM.getCoordinate() - offset;
+ float left = Frame.LEFT.getCoordinate();
+ float right = AspectRatioUtil.calculateRight(left, top, bottom, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ } else if (frame.equals(Frame.BOTTOM)) {
+ float bottom = imageRect.bottom;
+ float top = Frame.TOP.getCoordinate() - offset;
+ float left = Frame.LEFT.getCoordinate();
+ float right = AspectRatioUtil.calculateRight(left, top, bottom, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ }
+ break;
+ case BOTTOM:
+ if (frame.equals(Frame.LEFT)) {
+ float left = imageRect.left;
+ float right = Frame.RIGHT.getCoordinate() - offset;
+ float top = Frame.TOP.getCoordinate();
+ float bottom = AspectRatioUtil.calculateBottom(left, top, right, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ } else if (frame.equals(Frame.RIGHT)) {
+ float right = imageRect.right;
+ float left = Frame.LEFT.getCoordinate() - offset;
+ float top = Frame.TOP.getCoordinate();
+ float bottom = AspectRatioUtil.calculateBottom(left, top, right, aspectRatio);
+
+ return isOutOfBounds(top, left, bottom, right, imageRect);
+ }
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * 返回新矩形是否超出边界
+ *
+ * @param imageRect 要与之比较的图像
+ *
+ * @return 是否会越界
+ */
+ private boolean isOutOfBounds(float top, float left, float bottom, float right, RectFloat imageRect) {
+ return (!(top < imageRect.top) && !(left < imageRect.left) && !(bottom > imageRect.bottom) && !(right > imageRect.right));
+ }
+
+ /**
+ * 确定此框架是否在给定边框的内边距之外。边距通过SNAPRADIUS数量进入实际帧;因此,确定点是否在内部“边距”帧之外。
+ */
+ public boolean isOutsideMargin(RectFloat rect, float margin) {
+ boolean result;
+
+ switch (this) {
+ case LEFT:
+ result = mCoordinate - rect.left < margin;
+ break;
+ case TOP:
+ result = mCoordinate - rect.top < margin;
+ break;
+ case RIGHT:
+ result = rect.right - mCoordinate < margin;
+ break;
+ default: // BOTTOM
+ result = rect.bottom - mCoordinate < margin;
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * 在给定控制柄位置、图像边界框和捕捉半径的情况下,获取裁剪窗口左边缘的结果x位置。
+ *
+ * @param x 左边缘拖动到的x位置
+ * @param imageRect 正在裁剪的图像的边界框
+ * @param imageSnapRadius 到图像边缘的捕捉距离
+ *
+ * @return 左边缘的实际x位置
+ */
+ private static float adjustLeft(float x, RectFloat imageRect, float imageSnapRadius, float aspectRatio) {
+ float resultX;
+
+ if (x - imageRect.left < imageSnapRadius) {
+ resultX = imageRect.left;
+ } else {
+
+ // 选择要使用的三个可能值中的最小值
+ float resultXHoriz = Float.POSITIVE_INFINITY;
+ float resultXVert = Float.POSITIVE_INFINITY;
+
+ // 检查车窗是否水平过小
+ if (x >= Frame.RIGHT.getCoordinate() - MIN_CROP_LENGTH_PX) {
+ resultXHoriz = Frame.RIGHT.getCoordinate() - MIN_CROP_LENGTH_PX;
+ }
+
+ // 检查窗口是否垂直过小
+ if (((Frame.RIGHT.getCoordinate() - x) / aspectRatio) <= MIN_CROP_LENGTH_PX) {
+ resultXVert = Frame.RIGHT.getCoordinate() - (MIN_CROP_LENGTH_PX * aspectRatio);
+ }
+ resultX = Math.min(x, Math.min(resultXHoriz, resultXVert));
+ }
+ return resultX;
+ }
+
+ /**
+ * 在给定控制柄位置、图像边界框和捕捉半径的情况下,获取裁剪窗口右边缘的结果x位置。
+ *
+ * @param x 右边缘拖动到的x位置
+ * @param imageRect 正在裁剪的图像的边界框
+ * @param imageSnapRadius 到图像边缘的捕捉距离
+ *
+ * @return 右边缘的实际x位置
+ */
+ private static float adjustRight(float x, RectFloat imageRect, float imageSnapRadius, float aspectRatio) {
+ float resultX;
+
+ // 如果靠近边缘
+ if (imageRect.right - x < imageSnapRadius) {
+ resultX = imageRect.right;
+ } else {
+
+ // 选择要使用的三个可能值中的最大值
+ float resultXHoriz = Float.NEGATIVE_INFINITY;
+ float resultXVert = Float.NEGATIVE_INFINITY;
+
+ // 检查车窗是否水平过小
+ if (x <= Frame.LEFT.getCoordinate() + MIN_CROP_LENGTH_PX) {
+ resultXHoriz = Frame.LEFT.getCoordinate() + MIN_CROP_LENGTH_PX;
+ }
+ // 检查窗口是否垂直过小
+ if (((x - Frame.LEFT.getCoordinate()) / aspectRatio) <= MIN_CROP_LENGTH_PX) {
+ resultXVert = Frame.LEFT.getCoordinate() + (MIN_CROP_LENGTH_PX * aspectRatio);
+ }
+ resultX = Math.max(x, Math.max(resultXHoriz, resultXVert));
+ }
+ return resultX;
+ }
+
+ /**
+ * 在给定控制柄位置、图像边界框和捕捉半径的情况下,获取裁剪窗口上边缘的结果y位置。
+ *
+ * @param y 将上边缘拖动到的Y位置
+ * @param imageRect 正在裁剪的图像的边界框
+ * @param imageSnapRadius 到图像边缘的捕捉距离
+ *
+ * @return 上边缘的实际y位置
+ */
+ private static float adjustTop(float y,RectFloat imageRect, float imageSnapRadius, float aspectRatio) {
+ float resultY;
+
+ if (y - imageRect.top < imageSnapRadius) {
+ resultY = imageRect.top;
+ } else {
+
+ // 选择要使用的三个可能值中的最小值
+ float resultYVert = Float.POSITIVE_INFINITY;
+ float resultYHoriz = Float.POSITIVE_INFINITY;
+
+ // 检查窗口是否垂直过小
+ if (y >= Frame.BOTTOM.getCoordinate() - MIN_CROP_LENGTH_PX) {
+ resultYHoriz = Frame.BOTTOM.getCoordinate() - MIN_CROP_LENGTH_PX;
+ }
+ // 检查窗口是否水平过小
+ if (((Frame.BOTTOM.getCoordinate() - y) * aspectRatio) <= MIN_CROP_LENGTH_PX) {
+ resultYVert = Frame.BOTTOM.getCoordinate() - (MIN_CROP_LENGTH_PX / aspectRatio);
+ }
+ resultY = Math.min(y, Math.min(resultYHoriz, resultYVert));
+ }
+ return resultY;
+ }
+
+ /**
+ * 在给定控制柄位置、图像边界框和捕捉半径的情况下,获取裁剪窗口底部边缘的结果y位置。
+ *
+ * @param y 底边拖动到的Y位置
+ * @param imageRect 正在裁剪的图像的边界框
+ * @param imageSnapRadius 到图像边缘的捕捉距离
+ *
+ * @return 底边的实际y位置
+ */
+ private static float adjustBottom(float y, RectFloat imageRect, float imageSnapRadius, float aspectRatio) {
+ float resultY;
+
+ if (imageRect.bottom - y < imageSnapRadius) {
+ resultY = imageRect.bottom;
+ } else {
+
+ // 选择要使用的三个可能值中的最小值
+ float resultYVert = Float.NEGATIVE_INFINITY;
+ float resultYHoriz = Float.NEGATIVE_INFINITY;
+
+ // 检查窗口是否垂直过小
+ if (y <= Frame.TOP.getCoordinate() + MIN_CROP_LENGTH_PX) {
+ resultYVert = Frame.TOP.getCoordinate() + MIN_CROP_LENGTH_PX;
+ }
+ // 检查窗口是否水平过小
+ if (((y - Frame.TOP.getCoordinate()) * aspectRatio) <= MIN_CROP_LENGTH_PX) {
+ resultYHoriz = Frame.TOP.getCoordinate() + (MIN_CROP_LENGTH_PX / aspectRatio);
+ }
+ resultY = Math.max(y, Math.max(resultYHoriz, resultYVert));
+ }
+ return resultY;
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/border/FrameGroup.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/border/FrameGroup.java
new file mode 100644
index 0000000000000000000000000000000000000000..195a5359c6a55c08f0a4f3a47ecdf3f944f7e959
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/border/FrameGroup.java
@@ -0,0 +1,12 @@
+package com.crop.cropperlib.border;
+
+public class FrameGroup {
+
+ public Frame primary;
+ public Frame seconder;
+
+ public FrameGroup(Frame primaryFrame, Frame secondaryFrame) {
+ primary = primaryFrame;
+ seconder = secondaryFrame;
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/CenterHandler.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/CenterHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..63ce496996b16133bd462d0433a524f0e42ef147
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/CenterHandler.java
@@ -0,0 +1,53 @@
+package com.crop.cropperlib.handle;
+
+import com.crop.cropperlib.border.Frame;
+import ohos.agp.utils.RectFloat;
+
+class CenterHandler extends Handler {
+
+ CenterHandler() {
+ super(null, null);
+ }
+
+ @Override
+ void refreshCropWindow(float x, float y, RectFloat imageRect, float snapRadius) {
+ float left = Frame.LEFT.getCoordinate();
+ float top = Frame.TOP.getCoordinate();
+ float right = Frame.RIGHT.getCoordinate();
+ float bottom = Frame.BOTTOM.getCoordinate();
+
+ float currentCenterX = (left + right) / 2;
+ float currentCenterY = (top + bottom) / 2;
+ float offsetX = x - currentCenterX;
+ float offsetY = y - currentCenterY;
+
+ // 调整裁剪窗口
+ Frame.LEFT.offset(offsetX);
+ Frame.TOP.offset(offsetY);
+ Frame.RIGHT.offset(offsetX);
+ Frame.BOTTOM.offset(offsetY);
+
+ // 检查两边是否越界,然后修理
+ if (Frame.LEFT.isOutsideMargin(imageRect, snapRadius)) {
+ float offset = Frame.LEFT.snapToRect(imageRect);
+ Frame.RIGHT.offset(offset);
+ } else if (Frame.RIGHT.isOutsideMargin(imageRect, snapRadius)) {
+ float offset = Frame.RIGHT.snapToRect(imageRect);
+ Frame.LEFT.offset(offset);
+ }
+
+ // 检查我们是否在顶部或底部,越界需修复。
+ if (Frame.TOP.isOutsideMargin(imageRect, snapRadius)) {
+ float offset = Frame.TOP.snapToRect(imageRect);
+ Frame.BOTTOM.offset(offset);
+ } else if (Frame.BOTTOM.isOutsideMargin(imageRect, snapRadius)) {
+ float offset = Frame.BOTTOM.snapToRect(imageRect);
+ Frame.TOP.offset(offset);
+ }
+ }
+
+ @Override
+ void refreshCropWindow(float x, float y, float targetAspectRatio, RectFloat imageRect, float snapRadius) {
+ refreshCropWindow(x, y, imageRect, snapRadius);
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/CornerHandler.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/CornerHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..509d7852c6422a29e367051b443d8c7260aacc72
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/CornerHandler.java
@@ -0,0 +1,27 @@
+package com.crop.cropperlib.handle;
+
+import com.crop.cropperlib.border.Frame;
+import com.crop.cropperlib.border.FrameGroup;
+import ohos.agp.utils.RectFloat;
+
+class CornerHandler extends Handler {
+
+ CornerHandler(Frame horizontalFrame, Frame verticalFrame) {
+ super(horizontalFrame, verticalFrame);
+ }
+
+ @Override
+ void refreshCropWindow(float x, float y, float targetAspectRatio, RectFloat imageRect, float snapRadius) {
+ FrameGroup activeEdges = getActiveFrames(x, y, targetAspectRatio);
+ Frame primaryFrame = activeEdges.primary;
+ Frame secondaryFrame = activeEdges.seconder;
+
+ primaryFrame.adjustCoordinate(x, y, imageRect, snapRadius, targetAspectRatio);
+ secondaryFrame.adjustCoordinate(targetAspectRatio);
+
+ if (secondaryFrame.isOutsideMargin(imageRect, snapRadius)) {
+ secondaryFrame.snapToRect(imageRect);
+ primaryFrame.adjustCoordinate(targetAspectRatio);
+ }
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/Handle.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/Handle.java
new file mode 100644
index 0000000000000000000000000000000000000000..343b0e5287ec763b062f6eb6f6c4b96f24ac02ce
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/Handle.java
@@ -0,0 +1,34 @@
+package com.crop.cropperlib.handle;
+
+import com.crop.cropperlib.border.Frame;
+import ohos.agp.utils.RectFloat;
+
+/**
+ * 表示裁剪窗口上可按、可拖动的枚举
+ */
+public enum Handle {
+
+ TOP_LEFT(new CornerHandler(Frame.TOP, Frame.LEFT)),
+ TOP_RIGHT(new CornerHandler(Frame.TOP, Frame.RIGHT)),
+ BOTTOM_LEFT(new CornerHandler(Frame.BOTTOM, Frame.LEFT)),
+ BOTTOM_RIGHT(new CornerHandler(Frame.BOTTOM, Frame.RIGHT)),
+ LEFT(new VerticalHandler(Frame.LEFT)),
+ TOP(new HorizontalHandler(Frame.TOP)),
+ RIGHT(new VerticalHandler(Frame.RIGHT)),
+ BOTTOM(new HorizontalHandler(Frame.BOTTOM)),
+ CENTER(new CenterHandler());
+
+ private Handler mHelper;
+
+ Handle(Handler helper) {
+ mHelper = helper;
+ }
+
+ public void refreshCropWindow(float x, float y, RectFloat imageRect, float snapRadius) {
+ mHelper.refreshCropWindow(x, y, imageRect, snapRadius);
+ }
+
+ public void refreshCropWindow(float x, float y, float targetAspectRatio, RectFloat imageRect, float snapRadius) {
+ mHelper.refreshCropWindow(x, y, targetAspectRatio, imageRect, snapRadius);
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/Handler.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/Handler.java
new file mode 100644
index 0000000000000000000000000000000000000000..ddca18e991feade8224bd5d76230575fa567f9d4
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/Handler.java
@@ -0,0 +1,113 @@
+package com.crop.cropperlib.handle;
+
+import com.crop.cropperlib.border.Frame;
+import com.crop.cropperlib.border.FrameGroup;
+import com.crop.cropperlib.utils.AspectRatioUtil;
+import ohos.agp.utils.RectFloat;
+
+/**
+ * 来处理裁剪窗口的操作的抽象类
+ */
+abstract class Handler {
+ private static final float UNFIXED_ASPECT_RATIO_CONSTANT = 1;
+ private Frame mHorizontalFrame;
+ private Frame mVerticalFrame;
+
+ // 将Pair对象另存为成员变量,以避免每次调用getActiveEdge()时都必须实例化新对象。
+ private FrameGroup mActiveFrames;
+
+ /**
+ * @param horizontalFrame 水平边;可以为null
+ * @param verticalFrame 垂直边;可以为null
+ */
+ Handler(Frame horizontalFrame, Frame verticalFrame) {
+ mHorizontalFrame = horizontalFrame;
+ mVerticalFrame = verticalFrame;
+ mActiveFrames = new FrameGroup(mHorizontalFrame, mVerticalFrame);
+ }
+
+ /**
+ * 通过直接设置帧坐标来更新裁剪窗口
+ *
+ * @param x x坐标
+ * @param y y坐标
+ * @param imageRect 图像的边框
+ * @param snapRadius 裁剪窗口应捕捉到图像的最大距离
+ */
+ void refreshCropWindow(float x, float y, RectFloat imageRect, float snapRadius) {
+ FrameGroup activeFrames = getActiveFrames();
+ Frame primaryFrame = activeFrames.primary;
+ Frame secondaryFrame = activeFrames.seconder;
+
+ if (primaryFrame != null) {
+ primaryFrame.adjustCoordinate(x, y, imageRect, snapRadius, UNFIXED_ASPECT_RATIO_CONSTANT);
+ }
+ if (secondaryFrame != null) {
+ secondaryFrame.adjustCoordinate(x, y, imageRect, snapRadius, UNFIXED_ASPECT_RATIO_CONSTANT);
+ }
+ }
+
+ /**
+ * 通过直接设置帧坐标来更新裁剪窗口;此方法保持给定的纵横比
+ *
+ * @param x x坐标
+ * @param y y坐标
+ * @param targetAspectRatio 要保持的横纵比
+ * @param imageRect 图像的边框
+ * @param snapRadius 裁剪窗口应捕捉到图像的最大距离
+ */
+ abstract void refreshCropWindow(float x, float y, float targetAspectRatio, RectFloat imageRect, float snapRadius);
+
+ /**
+ * 获取关联的边(即拖动此句柄时应移动的边)。在不保持纵横比的情况下使用。
+ *
+ * @return 一组活动边
+ */
+ private FrameGroup getActiveFrames() {
+ return mActiveFrames;
+ }
+
+ /**
+ * 获取关联的边作为有序对。一对中的主边是决定边。当我们需要保持纵横比时使用这个方法。
+ *
+ * @param x 触点x坐标
+ * @param y 触点y坐标
+ * @param targetAspectRatio 需要保持的横纵比
+ *
+ * @return 一组活动边
+ */
+ FrameGroup getActiveFrames(float x, float y, float targetAspectRatio) {
+
+ // 如果将此控制柄拖动到给定的x-y坐标,则计算纵横比
+ final float potentialAspectRatio = getAspectRatio(x, y);
+
+ // 如果接触点比宽高比宽,那么x是确定的边。否则,y是决定性的一方
+ if (potentialAspectRatio > targetAspectRatio) {
+ mActiveFrames.primary = mVerticalFrame;
+ mActiveFrames.seconder = mHorizontalFrame;
+ } else {
+ mActiveFrames.primary = mHorizontalFrame;
+ mActiveFrames.seconder = mVerticalFrame;
+ }
+ return mActiveFrames;
+ }
+
+ /**
+ * 获取裁剪窗口的纵横比
+ *
+ * @param x x坐标
+ * @param y y坐标
+ *
+ * @return 纵横比
+ */
+ private float getAspectRatio(float x, float y) {
+
+ // 用给定的触摸坐标替换活动边坐标
+ float left = (mVerticalFrame == Frame.LEFT) ? x : Frame.LEFT.getCoordinate();
+ float top = (mHorizontalFrame == Frame.TOP) ? y : Frame.TOP.getCoordinate();
+ float right = (mVerticalFrame == Frame.RIGHT) ? x : Frame.RIGHT.getCoordinate();
+ float bottom = (mHorizontalFrame == Frame.BOTTOM) ? y : Frame.BOTTOM.getCoordinate();
+
+ return AspectRatioUtil.calculateAspectRatio(left, top, right, bottom);
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/HorizontalHandler.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/HorizontalHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..6602940938c44949302cdf8f5c1b9e4967eea887
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/HorizontalHandler.java
@@ -0,0 +1,57 @@
+package com.crop.cropperlib.handle;
+
+import com.crop.cropperlib.border.Frame;
+import com.crop.cropperlib.utils.AspectRatioUtil;
+import ohos.agp.utils.RectFloat;
+
+/**
+ * 水平处理器
+ */
+class HorizontalHandler extends Handler {
+
+ private Frame mFrame;
+
+ HorizontalHandler(Frame frame) {
+ super(frame, null);
+ mFrame = frame;
+ }
+
+ @Override
+ void refreshCropWindow(float x, float y, float targetAspectRatio, RectFloat imageRect, float snapRadius) {
+
+ // 相应地调整此框架
+ mFrame.adjustCoordinate(x, y, imageRect, snapRadius, targetAspectRatio);
+
+ float left = Frame.LEFT.getCoordinate();
+ float right = Frame.RIGHT.getCoordinate();
+
+ // 移动此帧后,裁剪窗口将失去比例
+ float targetWidth = AspectRatioUtil.calculateWidth(Frame.getHeight(), targetAspectRatio);
+
+ // 调整裁剪窗口,使其通过对称地移入或移出相邻边来保持给定的纵横比
+ float difference = targetWidth - Frame.getWidth();
+ float halfDifference = difference / 2;
+ left -= halfDifference;
+ right += halfDifference;
+
+ Frame.LEFT.setCoordinate(left);
+ Frame.RIGHT.setCoordinate(right);
+
+ // 检查两边是否越界,然后修理
+ if (Frame.LEFT.isOutsideMargin(imageRect, snapRadius)
+ && mFrame.isNewRectangleOutOfBounds(Frame.LEFT, imageRect, targetAspectRatio)) {
+
+ float offset = Frame.LEFT.snapToRect(imageRect);
+ Frame.RIGHT.offset(-offset);
+ mFrame.adjustCoordinate(targetAspectRatio);
+ }
+
+ if (Frame.RIGHT.isOutsideMargin(imageRect, snapRadius)
+ && mFrame.isNewRectangleOutOfBounds(Frame.RIGHT, imageRect, targetAspectRatio)) {
+
+ float offset = Frame.RIGHT.snapToRect(imageRect);
+ Frame.LEFT.offset(-offset);
+ mFrame.adjustCoordinate(targetAspectRatio);
+ }
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/VerticalHandler.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/VerticalHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9a1273bec7e89a629cf059179ca4612162ef7ca
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/handle/VerticalHandler.java
@@ -0,0 +1,57 @@
+package com.crop.cropperlib.handle;
+
+import com.crop.cropperlib.border.Frame;
+import com.crop.cropperlib.utils.AspectRatioUtil;
+import ohos.agp.utils.RectFloat;
+
+/**
+ * 垂直处理器
+ */
+class VerticalHandler extends Handler {
+
+ private Frame mFrame;
+
+ VerticalHandler(Frame frame) {
+ super(null, frame);
+ mFrame = frame;
+ }
+
+ @Override
+ void refreshCropWindow(float x, float y, float targetAspectRatio, RectFloat imageRect, float snapRadius) {
+
+ // 相应地调整此框架.
+ mFrame.adjustCoordinate(x, y, imageRect, snapRadius, targetAspectRatio);
+
+ float top = Frame.TOP.getCoordinate();
+ float bottom = Frame.BOTTOM.getCoordinate();
+
+ // 移动此帧后,裁剪窗口将失去比例
+ float targetHeight = AspectRatioUtil.calculateHeight(Frame.getWidth(), targetAspectRatio);
+
+ // 调整裁剪窗口,使其通过对称地移入或移出相邻边来保持给定的纵横比
+ float difference = targetHeight - Frame.getHeight();
+ float halfDifference = difference / 2;
+ top -= halfDifference;
+ bottom += halfDifference;
+
+ Frame.TOP.setCoordinate(top);
+ Frame.BOTTOM.setCoordinate(bottom);
+
+ // 检查我们是否在顶部或底部越界,并修复
+ if (Frame.TOP.isOutsideMargin(imageRect, snapRadius)
+ && mFrame.isNewRectangleOutOfBounds(Frame.TOP, imageRect, targetAspectRatio)) {
+
+ float offset = Frame.TOP.snapToRect(imageRect);
+ Frame.BOTTOM.offset(-offset);
+ mFrame.adjustCoordinate(targetAspectRatio);
+ }
+
+ if (Frame.BOTTOM.isOutsideMargin(imageRect, snapRadius)
+ && mFrame.isNewRectangleOutOfBounds(Frame.BOTTOM, imageRect, targetAspectRatio)) {
+
+ float offset = Frame.BOTTOM.snapToRect(imageRect);
+ Frame.TOP.offset(-offset);
+ mFrame.adjustCoordinate(targetAspectRatio);
+ }
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/AspectRatioUtil.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/AspectRatioUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..bbc7640a437be684b13ca87a745d621c0dfec960
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/AspectRatioUtil.java
@@ -0,0 +1,58 @@
+package com.crop.cropperlib.utils;
+
+/**
+ * 用于处理涉及固定纵横比的计算的实用程序类
+ */
+public class AspectRatioUtil {
+
+ /**
+ * 计算给定矩形的纵横比
+ */
+ public static float calculateAspectRatio(float left, float top, float right, float bottom) {
+ float width = right - left;
+ float height = bottom - top;
+ return width / height;
+ }
+
+ /**
+ * 计算给定矩形其他边和纵横比的左边缘的x坐标
+ */
+ public static float calculateLeft(float top, float right, float bottom, float targetAspectRatio) {
+ return right - (targetAspectRatio * (bottom - top));
+ }
+
+ /**
+ * 计算给定矩形其他边和纵横比的顶边的y坐标
+ */
+ public static float calculateTop(float left, float right, float bottom, float targetAspectRatio) {
+ return bottom - ((right - left) / targetAspectRatio);
+ }
+
+ /**
+ * 在给定矩形其他边和纵横比的情况下,计算右边缘的x坐标。
+ */
+ public static float calculateRight(float left, float top, float bottom, float targetAspectRatio) {
+ return (targetAspectRatio * (bottom - top)) + left;
+ }
+
+ /**
+ * 计算给定矩形其他边和纵横比的底边的y坐标
+ */
+ public static float calculateBottom(float left, float top, float right, float targetAspectRatio) {
+ return ((right - left) / targetAspectRatio) + top;
+ }
+
+ /**
+ * 计算给定上、下边缘和纵横比的矩形的宽度
+ */
+ public static float calculateWidth(float height, float targetAspectRatio) {
+ return targetAspectRatio * height;
+ }
+
+ /**
+ * 计算给定左右边和纵横比的矩形的高度
+ */
+ public static float calculateHeight(float width, float targetAspectRatio) {
+ return width / targetAspectRatio;
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/HandleUtil.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/HandleUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..b21f2faf104a61b8d82d9beda3842636853e4466
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/HandleUtil.java
@@ -0,0 +1,192 @@
+package com.crop.cropperlib.utils;
+
+import com.crop.cropperlib.handle.Handle;
+import ohos.agp.utils.Point;
+
+public class HandleUtil {
+ /**
+ * 确定在给定触摸坐标、边界框和触摸半径的情况下按下哪个控制柄(如果有)
+ *
+ * @param x 触点X坐标
+ * @param y 触点X坐标
+ * @param left 左边界的x坐标
+ * @param top 上界的y坐标
+ * @param right 右边界的x坐标
+ * @param bottom 下边界的y坐标
+ * @param targetRadius 以像素为单位的目标半径
+ *
+ * @return Handle
+ */
+ public static Handle getPressedHandle(float x,
+ float y,
+ float left,
+ float top,
+ float right,
+ float bottom,
+ float targetRadius) {
+
+ // 找到离接触点最近的角把手。
+ // 如果接触点位于最近手柄的目标区域,则这是按下的手柄。
+ // 否则,请检查是否有任何边位于接触点的目标区域。
+ // 否则,请检查触摸点是否在裁剪窗口范围内;如果在范围内,请选择中心控制柄。
+ Handle closestHandle = null;
+ float closestDistance = Float.POSITIVE_INFINITY;
+
+ final float distanceToTopLeft = MathUtil.calculateDistance(x, y, left, top);
+ if (distanceToTopLeft < closestDistance) {
+ closestDistance = distanceToTopLeft;
+ closestHandle = Handle.TOP_LEFT;
+ }
+
+ final float distanceToTopRight = MathUtil.calculateDistance(x, y, right, top);
+ if (distanceToTopRight < closestDistance) {
+ closestDistance = distanceToTopRight;
+ closestHandle = Handle.TOP_RIGHT;
+ }
+
+ final float distanceToBottomLeft = MathUtil.calculateDistance(x, y, left, bottom);
+ if (distanceToBottomLeft < closestDistance) {
+ closestDistance = distanceToBottomLeft;
+ closestHandle = Handle.BOTTOM_LEFT;
+ }
+
+ final float distanceToBottomRight = MathUtil.calculateDistance(x, y, right, bottom);
+ if (distanceToBottomRight < closestDistance) {
+ closestDistance = distanceToBottomRight;
+ closestHandle = Handle.BOTTOM_RIGHT;
+ }
+
+ if (closestDistance <= targetRadius) {
+ return closestHandle;
+ }
+
+ // 如果我们到达这一点,没有一个角处理器在触摸目标区域,我们需要检查边缘。
+ if (HandleUtil.isInHorizontalTargetZone(x, y, left, right, top, targetRadius)) {
+ return Handle.TOP;
+ } else if (HandleUtil.isInHorizontalTargetZone(x, y, left, right, bottom, targetRadius)) {
+ return Handle.BOTTOM;
+ } else if (HandleUtil.isInVerticalTargetZone(x, y, left, top, bottom, targetRadius)) {
+ return Handle.LEFT;
+ } else if (HandleUtil.isInVerticalTargetZone(x, y, right, top, bottom, targetRadius)) {
+ return Handle.RIGHT;
+ }
+
+ // 如果我们到达这一点,没有一个角落或边缘是在触摸目标区。
+ // 检查触摸点是否在裁剪窗口的范围内。如果是,请选择中心控制柄。
+ if (isWithinBounds(x, y, left, top, right, bottom)) {
+ return Handle.CENTER;
+ }
+ return Handle.CENTER;
+ }
+
+ /**
+ * 计算接触点相对于指定控制柄的精确位置的偏移
+ *
+ * 偏移量将在“touchOffsetOutput”参数中返回;x偏移量将是第一个值,y偏移量将是第二个值。
+ */
+ public static void getOffset(Handle handle,
+ float x,
+ float y,
+ float left,
+ float top,
+ float right,
+ float bottom,
+ Point touchOffsetOutput) {
+
+ float touchOffsetX = 0;
+ float touchOffsetY = 0;
+
+ // 计算与相应控制柄的偏移
+ switch (handle) {
+
+ case TOP_LEFT:
+ touchOffsetX = left - x;
+ touchOffsetY = top - y;
+ break;
+ case TOP_RIGHT:
+ touchOffsetX = right - x;
+ touchOffsetY = top - y;
+ break;
+ case BOTTOM_LEFT:
+ touchOffsetX = left - x;
+ touchOffsetY = bottom - y;
+ break;
+ case BOTTOM_RIGHT:
+ touchOffsetX = right - x;
+ touchOffsetY = bottom - y;
+ break;
+ case LEFT:
+ touchOffsetX = left - x;
+ touchOffsetY = 0;
+ break;
+ case TOP:
+ touchOffsetX = 0;
+ touchOffsetY = top - y;
+ break;
+ case RIGHT:
+ touchOffsetX = right - x;
+ touchOffsetY = 0;
+ break;
+ case BOTTOM:
+ touchOffsetX = 0;
+ touchOffsetY = bottom - y;
+ break;
+ case CENTER:
+ final float centerX = (right + left) / 2;
+ final float centerY = (top + bottom) / 2;
+ touchOffsetX = centerX - x;
+ touchOffsetY = centerY - y;
+ break;
+ }
+
+ touchOffsetOutput.modify(touchOffsetX, touchOffsetY);
+ }
+
+ /**
+ * 确定指定的坐标是否位于水平条控制柄的目标触摸区域中
+ *
+ * @param x 触点x坐标
+ * @param y 触点Y坐标
+ * @param handleXStart 水平滑动条的左x坐标
+ * @param handleXEnd 水平滑动条的右x坐标
+ * @param handleY 水平滑动条的Y坐标
+ * @param targetRadius 以像素为单位的目标半径
+ *
+ * @return 如果接触点位于目标接触区,则为true;否则为false
+ */
+ private static boolean isInHorizontalTargetZone(float x,
+ float y,
+ float handleXStart,
+ float handleXEnd,
+ float handleY,
+ float targetRadius) {
+
+ return (x > handleXStart && x < handleXEnd && Math.abs(y - handleY) <= targetRadius);
+ }
+
+ /**
+ * 确定指定的坐标是否位于垂直条控制柄的目标触摸区域中
+ *
+ * @param x 触点x坐标
+ * @param y 触点Y坐标
+ * @param handleX 垂直滑动条的Y坐标
+ * @param handleYStart 垂直滑动条的顶部Y坐标
+ * @param handleYEnd 垂直滑动条的底部Y坐标
+ * @param targetRadius 以像素为单位的目标半径
+ *
+ * @return 如果接触点位于目标接触区,则为true;否则为false
+ */
+ private static boolean isInVerticalTargetZone(float x,
+ float y,
+ float handleX,
+ float handleYStart,
+ float handleYEnd,
+ float targetRadius) {
+
+ return (Math.abs(x - handleX) <= targetRadius && y > handleYStart && y < handleYEnd);
+ }
+
+ private static boolean isWithinBounds(float x, float y, float left, float top, float right, float bottom) {
+ return x >= left && x <= right && y >= top && y <= bottom;
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/MathUtil.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/MathUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..b582bda6894818b8c389de9555ecc0b3ee040d7f
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/MathUtil.java
@@ -0,0 +1,13 @@
+package com.crop.cropperlib.utils;
+
+class MathUtil {
+
+ /**
+ * 计算两点(x1,y1)和(x2,y2)之间的距离。
+ */
+ static float calculateDistance(float x1, float y1, float x2, float y2) {
+ float side1 = x2 - x1;
+ float side2 = y2 - y1;
+ return (float) Math.sqrt(side1 * side1 + side2 * side2);
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/PaintUtil.java b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/PaintUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f3f2ad0dcb15f0ad6f01fe8c8f1e0a28ee05497
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/java/com/crop/cropperlib/utils/PaintUtil.java
@@ -0,0 +1,48 @@
+package com.crop.cropperlib.utils;
+
+import ohos.agp.render.Paint;
+import ohos.agp.utils.Color;
+
+/**
+ * 用于绘制CropOverlayView
+ */
+public class PaintUtil {
+ private static final int BORDER_COLOR = 0xAAFFFFFF;
+ private static final int GUIDELINE_COLOR = 0xAAFFFFFF;
+ private static final int SURROUNDING_AREA_COLOR = 0xB0000000;
+ private static final float FLOAT_BORDER = 3;
+ private static final float FLOAT_GUIDELINE = 1;
+
+ /**
+ * 创建绘制裁剪窗口边框的绘制对象
+ */
+ public static Paint getBorderPaint() {
+ Paint paint = new Paint();
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ paint.setStrokeWidth(FLOAT_BORDER);
+ paint.setColor(new Color(BORDER_COLOR));
+ return paint;
+ }
+
+ /**
+ * 创建绘制裁剪窗口准则的绘制对象
+ */
+ public static Paint getGuidelinePaint() {
+ Paint paint = new Paint();
+ paint.setStyle(Paint.Style.STROKE_STYLE);
+ paint.setStrokeWidth(FLOAT_GUIDELINE);
+ paint.setColor(new Color(GUIDELINE_COLOR));
+ return paint;
+ }
+
+ /**
+ * 创建用于在裁剪窗口外绘制半透明覆盖的绘制对象.
+ *
+ */
+ public static Paint getSurroundingAreaPaint() {
+ Paint paint = new Paint();
+ paint.setStyle(Paint.Style.FILL_STYLE);
+ paint.setColor(new Color(SURROUNDING_AREA_COLOR));
+ return paint;
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/resources/base/element/string.json b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..fda09f756eb50968ef9fd8e1fe8a196d6612832e
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/cropperlib/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "CropperLib"
+ }
+ ]
+}
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/.gitignore b/020.Cropper_OpenHarmony-master/cropper/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/build.gradle b/020.Cropper_OpenHarmony-master/cropper/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..973e137843cc20ec09ad5a9124a9a1fd149083fb
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/build.gradle
@@ -0,0 +1,23 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ compile project(path: ':cropperlib')
+ ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100'
+}
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/libs/cropperlib-debug.har b/020.Cropper_OpenHarmony-master/cropper/entry/libs/cropperlib-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..ac6cefb3de96451b21406fcf7d8a802abaa46f2e
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/entry/libs/cropperlib-debug.har differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/config.json b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..a33c98f9c800412bc7e34df1313bcd705c3a752f
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/config.json
@@ -0,0 +1,50 @@
+{
+ "app": {
+ "bundleName": "com.example.cropper",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.cropper",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry",
+ "installationFree": true
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.cropper.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/MainAbility.java b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd608bb8c5688d44f59133c5ab2c43dcf9c75cb0
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.cropper;
+
+import com.example.cropper.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/MyApplication.java b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1b0fb23d74ed87a7ecccaafb4b49038883c9f59
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.cropper;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/slice/MainAbilitySlice.java b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d4aa933e4c9704500b387ec39a659249c20c4ea
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/java/com/example/cropper/slice/MainAbilitySlice.java
@@ -0,0 +1,43 @@
+package com.example.cropper.slice;
+
+import com.crop.cropperlib.CropImage;
+import com.example.cropper.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.image.PixelMap;
+
+public class MainAbilitySlice extends AbilitySlice {
+ private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+
+ Button cropButton = (Button) findComponentById(ResourceTable.Id_cropButton);
+ cropButton.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ Image image = (Image) findComponentById(ResourceTable.Id_image);
+ CropImage cropImage = (CropImage) findComponentById(ResourceTable.Id_cropImage);
+
+ PixelMap pixelMap = cropImage.getCroppedImage();
+ image.setPixelMap(pixelMap);
+ }
+ });
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/element/string.json b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..0f03c8b5ee6de235823a7de11b3926bb29721a03
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Cropper"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/graphic/background_ability_main.xml b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/graphic/background_button.xml b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/graphic/background_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..668c5c813c4e3cfe99445bcf4bddf1ec5e218235
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/graphic/background_button.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/layout/ability_main.xml b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5fe128b4628c5c3c483be418860c57599bf49a93
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/black.jpg b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/black.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3c55b3d227364249af307f90f4699550e9ae88f6
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/black.jpg differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/blank.jpg b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/blank.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e22236207545bacfd18ffa150853d79a0a535d54
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/blank.jpg differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/icon.png b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/icon.png differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/mantis.PNG b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/mantis.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..d22270152c227ee30e752c72cac2a54d6a9de2ec
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/mantis.PNG differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/skiing.PNG b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/skiing.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..9f07d5db128c28cb739c96f98362c9255df95e87
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/entry/src/main/resources/base/media/skiing.PNG differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/entry/src/test/java/com/example/cropper/ExampleTest.java b/020.Cropper_OpenHarmony-master/cropper/entry/src/test/java/com/example/cropper/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d400b4b72ac1a6a81c7defc40950ea355b34c537
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/entry/src/test/java/com/example/cropper/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.cropper;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/020.Cropper_OpenHarmony-master/cropper/gradle.properties b/020.Cropper_OpenHarmony-master/cropper/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/020.Cropper_OpenHarmony-master/cropper/gradle/wrapper/gradle-wrapper.jar b/020.Cropper_OpenHarmony-master/cropper/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/020.Cropper_OpenHarmony-master/cropper/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/020.Cropper_OpenHarmony-master/cropper/gradle/wrapper/gradle-wrapper.properties b/020.Cropper_OpenHarmony-master/cropper/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/020.Cropper_OpenHarmony-master/cropper/gradlew b/020.Cropper_OpenHarmony-master/cropper/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/020.Cropper_OpenHarmony-master/cropper/gradlew.bat b/020.Cropper_OpenHarmony-master/cropper/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/020.Cropper_OpenHarmony-master/cropper/settings.gradle b/020.Cropper_OpenHarmony-master/cropper/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..47c3d6c4499249aec95410ce1e4e8438a45599dc
--- /dev/null
+++ b/020.Cropper_OpenHarmony-master/cropper/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':cropperlib'
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.gitignore b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/.gitignore b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/compiler.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/gradle.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f0b6549e50dad37933cc5898dc35391764feb555
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/gradle.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/jarRepositories.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/misc.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/phone/phoneSettingConfig_-1675685652.json b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/phone/phoneSettingConfig_-1675685652.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/phone/phoneSettingConfig_-1675685652.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/phone/phoneSettingConfig_1000637589.json b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/phone/phoneSettingConfig_1000637589.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/phone/phoneSettingConfig_1000637589.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/previewConfig.json b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..569ccca48d12257d9ca6d86ef3ed58a65c4f7594
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/previewer/previewConfig.json
@@ -0,0 +1,12 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\workspace\\MyApplication10\\entry": [
+ "phone"
+ ],
+ "D:\\PCFile\\PCFile\\svn\\024.subsampling-scale-image-view\\SubScaleView\\MyApplication10\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/vcs.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2365ab11f9ba6b763735c8fd976420234bb3521
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/021.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204SubScaleView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/021.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204SubScaleView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..59b0ee624107839bb5c456918f1f6668453d8789
Binary files /dev/null and "b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/021.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204SubScaleView\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/build.gradle b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0da9bc913f7350fad9087d8535f200bedce92ed3
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/.gitignore b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/build.gradle b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..432b961dfc57da06e74158f2debdab06fbcaaf30
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/libs/subscaleviewlibrary-debug.har b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/libs/subscaleviewlibrary-debug.har
new file mode 100644
index 0000000000000000000000000000000000000000..778bf3ba6f6aa46d52a965c643c9287681b71ec5
Binary files /dev/null and b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/libs/subscaleviewlibrary-debug.har differ
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/config.json b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..2628658d32ab3b886af663ade3e823cd6782a050
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/config.json
@@ -0,0 +1,85 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication10",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.myapplication10",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.myapplication10.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:label_name",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.example.myapplication10.AbilityOne",
+ "icon": "$media:icon",
+ "description": "$string:abilityone_description",
+ "label": "$string:label_name2",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.example.myapplication10.AbilityTwo",
+ "icon": "$media:icon",
+ "description": "$string:abilitytwo_description",
+ "label": "$string:label_name2",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.example.myapplication10.AbilityThree",
+ "icon": "$media:icon",
+ "description": "$string:abilitythree_description",
+ "label": "$string:label_name2",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.example.myapplication10.AbilityFour",
+ "icon": "$media:icon",
+ "description": "$string:abilityfour_description",
+ "label": "$string:label_name2",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityFour.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityFour.java
new file mode 100644
index 0000000000000000000000000000000000000000..46dcb5ce354386ecfc86e8fd78e95ec9bf909521
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityFour.java
@@ -0,0 +1,13 @@
+package com.example.myapplication10;
+
+import com.example.myapplication10.slice.AbilityFourSlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class AbilityFour extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(AbilityFourSlice.class.getName());
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityOne.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityOne.java
new file mode 100644
index 0000000000000000000000000000000000000000..12ae30dec1ce00fb4bc7a03c0e4b5c8356e7265c
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityOne.java
@@ -0,0 +1,13 @@
+package com.example.myapplication10;
+
+import com.example.myapplication10.slice.AbilityOneSlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class AbilityOne extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(AbilityOneSlice.class.getName());
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityThree.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityThree.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd9234638b184dbbfd81232fe8d72299a96caa47
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityThree.java
@@ -0,0 +1,13 @@
+package com.example.myapplication10;
+
+import com.example.myapplication10.slice.AbilityThreeSlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class AbilityThree extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(AbilityThreeSlice.class.getName());
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityTwo.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityTwo.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee3a586d1cc9138bd3d433571d5519dc38ac3fa2
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/AbilityTwo.java
@@ -0,0 +1,13 @@
+package com.example.myapplication10;
+
+import com.example.myapplication10.slice.AbilityTwoSlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class AbilityTwo extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(AbilityTwoSlice.class.getName());
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/MainAbility.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..2de5eb9911122e09c9baedec30ad37a2b4ea0a6a
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.myapplication10;
+
+import com.example.myapplication10.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/MyApplication.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..b56f2cc18008e323defbfee2ab5ffb647eb04e4c
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.myapplication10;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityFourSlice.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityFourSlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b07bdadfd3f8d5c2a0768a13b95ecc9893a1357
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityFourSlice.java
@@ -0,0 +1,32 @@
+package com.example.myapplication10.slice;
+
+import com.example.myapplication10.ResourceTable;
+import com.example.subscaleviewlibrary.ScalePivotImage;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Image;
+
+public class AbilityFourSlice extends AbilitySlice {
+
+ private ScalePivotImage scaleImage;
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_four);
+
+ Image image = (Image) findComponentById(ResourceTable.Id_image1);
+ scaleImage = new ScalePivotImage(image);
+ scaleImage.setScaleNum2(10);
+ image.setTouchEventListener(new ScalePivotImage.MyTouchListener());
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityOneSlice.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityOneSlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..07228966ff3ef8cc28d55882ba23a5af604ca501
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityOneSlice.java
@@ -0,0 +1,30 @@
+package com.example.myapplication10.slice;
+
+import com.example.myapplication10.ResourceTable;
+import com.example.subscaleviewlibrary.ScaleImage;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Image;
+
+public class AbilityOneSlice extends AbilitySlice {
+ private ScaleImage scaleImage;
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_one);
+ Image image = (Image) findComponentById(ResourceTable.Id_image1);
+ scaleImage = new ScaleImage(image);
+ scaleImage.setScaleNum2(3);
+ image.setTouchEventListener(new ScaleImage.MyTouchListener());
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityThreeSlice.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityThreeSlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..847e9d826b3205eacb932d17d99531cb415d1be9
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityThreeSlice.java
@@ -0,0 +1,40 @@
+package com.example.myapplication10.slice;
+
+import com.example.myapplication10.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.PageSlider;
+
+public class AbilityThreeSlice extends AbilitySlice {
+
+ private ViewPagerAdapter adapter;
+
+ private PageSlider pageSlider;
+
+
+ private static final int[] RES = new int[]{com.example.myapplication10.ResourceTable.Media_card,
+ com.example.myapplication10.ResourceTable.Media_sanmartino,
+ com.example.myapplication10.ResourceTable.Media_swissroad};
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_three);
+
+ // 初始化ViewPager 相关
+ pageSlider = (PageSlider) findComponentById(ResourceTable.Id_viewpager);
+ adapter = new ViewPagerAdapter(this, RES);
+
+ // pageslider绑定数据
+ pageSlider.setProvider(adapter);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityTwoSlice.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityTwoSlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..1267f6493c589decf27b560ec60bc261c2067c50
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/AbilityTwoSlice.java
@@ -0,0 +1,30 @@
+package com.example.myapplication10.slice;
+
+import com.example.myapplication10.ResourceTable;
+import com.example.subscaleviewlibrary.RotationImage;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+
+public class AbilityTwoSlice extends AbilitySlice {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_two);
+ Image image = (Image) findComponentById(ResourceTable.Id_image1);
+ RotationImage rotationImage = new RotationImage(image);
+ Component button = findComponentById(ResourceTable.Id_button);
+ button.setClickedListener(rotationImage);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/MainAbilitySlice.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5caedbf4fad3e573aac0febac7a902d0bdfd6ff
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/MainAbilitySlice.java
@@ -0,0 +1,73 @@
+package com.example.myapplication10.slice;
+
+import com.example.myapplication10.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.utils.Rect;
+
+public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener{
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ findComponentById(ResourceTable.Id_button1).setClickedListener(this);
+ findComponentById(ResourceTable.Id_button2).setClickedListener(this);
+ findComponentById(ResourceTable.Id_button3).setClickedListener(this);
+ findComponentById(ResourceTable.Id_button4).setClickedListener(this);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+ @Override
+ public void onClick(Component component) {
+ Operation operation;
+ Intent secondIntent = new Intent();
+ // 指定待启动FA的bundleName和abilityName
+ switch (component.getId()) {
+ case ResourceTable.Id_button1:
+ operation = new Intent.OperationBuilder()
+ .withDeviceId("")
+ .withBundleName("com.example.myapplication10")
+ .withAbilityName("com.example.myapplication10.AbilityOne")
+ .build();
+ secondIntent.setOperation(operation);
+ break;
+ case ResourceTable.Id_button2:
+ operation = new Intent.OperationBuilder()
+ .withDeviceId("")
+ .withBundleName("com.example.myapplication10")
+ .withAbilityName("com.example.myapplication10.AbilityTwo")
+ .build();
+ secondIntent.setOperation(operation);
+ break;
+ case ResourceTable.Id_button3:
+ operation = new Intent.OperationBuilder()
+ .withDeviceId("")
+ .withBundleName("com.example.myapplication10")
+ .withAbilityName("com.example.myapplication10.AbilityThree")
+ .build();
+ secondIntent.setOperation(operation);
+ break;
+ case ResourceTable.Id_button4:
+ operation = new Intent.OperationBuilder()
+ .withDeviceId("")
+ .withBundleName("com.example.myapplication10")
+ .withAbilityName("com.example.myapplication10.AbilityFour")
+ .build();
+ secondIntent.setOperation(operation);
+ break;
+ }
+ startAbility(secondIntent); // 通过AbilitySlice的startAbility接口实现启动另一个页面
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/ViewPagerAdapter.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/ViewPagerAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ac88ddec57d5ebef2bc307fa1100ebfdf086ade
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/java/com/example/myapplication10/slice/ViewPagerAdapter.java
@@ -0,0 +1,43 @@
+package com.example.myapplication10.slice;
+
+import com.example.myapplication10.ResourceTable;
+import ohos.agp.components.*;
+import ohos.app.Context;
+
+/**
+ * Created by zhouwei on 17/5/22.
+ */
+
+public class ViewPagerAdapter extends PageSliderProvider {
+ private Context mContext;
+ private int[] RES;
+ public ViewPagerAdapter(Context context, int[] RES) {
+ mContext = context;
+ this.RES = RES;
+ }
+
+ @Override
+ public int getCount() {
+ return RES.length;
+ }
+
+ @Override
+ public Object createPageInContainer(ComponentContainer componentContainer, int i) {
+ Component view = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_view_pager_item,null,false);
+ Image imageView = (Image) view.findComponentById(com.example.myapplication10.ResourceTable.Id_item_image);
+ imageView.setPixelMap(RES[i]);
+ componentContainer.addComponent(view);
+ return view;
+ }
+
+ @Override
+ public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
+ componentContainer.removeComponent((Component) o);
+
+ }
+
+ @Override
+ public boolean isPageMatchToObject(Component component, Object o) {
+ return component == o;
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/element/string.json b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..8ee336ea3c5466eb1844e3837e3a6f71fa673039
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,36 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication10"
+ },
+ {
+ "name": "label_name",
+ "value": "MyApplication10"
+ },
+ {
+ "name": "label_name2",
+ "value": "entry"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "abilityone_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "abilitytwo_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "abilitythree_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "abilityfour_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/graphic/background_ability_main.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..80fca8cc4a8ded8e20576eb07c5494f42ce83e41
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_four.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_four.xml
new file mode 100644
index 0000000000000000000000000000000000000000..89a326e3cd252534ddf60c24051baff20f12ccfe
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_four.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_main.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1c3248fb190bf5bdf75575039f0dc4463a314624
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_one.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_one.xml
new file mode 100644
index 0000000000000000000000000000000000000000..efd1e7f1b999ecae401dd2668a465bd8f1ab198e
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_one.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_three.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_three.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a60ebd16bd2f5a44b7cad3fcec0a999ed79870e0
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_three.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_two.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_two.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b4cf339bac03da2cf9fbcbfe440d1fd2f2dadde8
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/ability_two.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/view_pager_item.xml b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/view_pager_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f94b872a20539e9d08eef772d0e358cbe11f7438
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/layout/view_pager_item.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/card.png b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/card.png
new file mode 100644
index 0000000000000000000000000000000000000000..20f330b51de02e3d5c9189e986cb7c80ccbb2fb0
Binary files /dev/null and b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/card.png differ
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/icon.png b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/icon.png differ
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/sanmartino.jpg b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/sanmartino.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..faf7a5116c8966be2160a2d296e71d3b9f271613
Binary files /dev/null and b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/sanmartino.jpg differ
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/swissroad.jpg b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/swissroad.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3a3215130f805f08942712858d4990d062681850
Binary files /dev/null and b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/main/resources/base/media/swissroad.jpg differ
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/test/java/com/example/myapplication10/ExampleTest.java b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/test/java/com/example/myapplication10/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..171c4b34a212e4da6afe454abb0c4f28cfa4999f
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/entry/src/test/java/com/example/myapplication10/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.myapplication10;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle.properties b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle/wrapper/gradle-wrapper.jar b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle/wrapper/gradle-wrapper.properties b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradlew b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradlew.bat b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/settings.gradle b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..4773db73233a570c2d0c01a22e75321acfbf7a07
--- /dev/null
+++ b/021.subsampling-scale-image-view_OpenHarmony-master/SubScaleView/MyApplication10/settings.gradle
@@ -0,0 +1 @@
+include ':entry'
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.gitignore b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/.gitignore b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/compiler.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/gradle.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..16145089939d7082847bb798c990e33e4a182752
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/jarRepositories.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/misc.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1542005666.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1542005666.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1542005666.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1753682269.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1753682269.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1753682269.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1836425718.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1836425718.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/phone/phoneSettingConfig_1836425718.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/previewConfig.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..a2b00f3eb5d728ce80ac2dde99ed086d26f2b1a9
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/previewer/previewConfig.json
@@ -0,0 +1,15 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "E:\\HarmonyPlayer\\entry": [
+ "phone"
+ ],
+ "D:\\PCFile\\PCFile\\svn\\025.HarmonyPlayer\\VideoPlayer\\playerHarmonyos": [
+ "phone"
+ ],
+ "D:\\PCFile\\PCFile\\thirdcomponent\\thirdcomponent\\08.HarmonyPlayer\\VideoPlayer\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/vcs.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..64713b81f3557f6879e5fe4965dcc1348e60fb9c
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/022.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PlayerComponent\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/022.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PlayerComponent\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..1ca4223e4b9c7e02f8582c1853e94fe52ffc712a
Binary files /dev/null and "b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/022.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204PlayerComponent\347\273\204\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/build.gradle b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..c6a8405a9511c949174dbf6f77b6224d67ecfc5a
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/build.gradle
@@ -0,0 +1,43 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+// maven {
+// url 'http://localhost:8888/repository/maven-releases/'
+// }
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+// maven {
+// url 'http://10.61.181.54:8081/repository/maven-releases/'
+// }
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/.gitignore b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/build.gradle b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..dffa9bfa1a661706a6e8b00aa01f28f8bbbfac53
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testCompile'junit:junit:4.12'
+ implementation(project(':playerHarmonyos'))
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/config.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..fc588f4b4c8f0efa94b0985608ee74a5d5efbcfa
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/config.json
@@ -0,0 +1,69 @@
+{
+ "app": {
+ "bundleName": "com.example.harmonyplayer",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {
+ "default": {
+ "network": {
+ "cleartextTraffic": true
+ }
+ }
+ },
+ "module": {
+ "package": "com.example.harmonyplayer",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.harmonyplayer.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:label_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "metaData": {
+ "customizeData": [
+ {
+ "extra": "",
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar"
+ }
+ ]
+ },
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.INTERNET"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/MainAbility.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..48d5c182ef72b66803d0ba06eebfd39fcd3a82c8
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/MainAbility.java
@@ -0,0 +1,18 @@
+package com.example.harmonyplayer;
+
+import com.example.harmonyplayer.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+/**
+ * @author xxwangcw
+ * MainAbility
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/MyApplication.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..70024a14295b223062ccd2d945e3939f3e6934ed
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/MyApplication.java
@@ -0,0 +1,14 @@
+package com.example.harmonyplayer;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * @author xxwangcw
+ * MyApplication
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/slice/MainAbilitySlice.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..4886c26a2f06275592fb2e3e23a7087c3d5c51b5
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/java/com/example/harmonyplayer/slice/MainAbilitySlice.java
@@ -0,0 +1,43 @@
+package com.example.harmonyplayer.slice;
+
+import com.example.harmonyplayer.ResourceTable;
+import com.example.playerharmonyos.HarmonyPlayerComponent;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.app.Context;
+
+/**
+ * MainAbilitySlice
+ */
+public class MainAbilitySlice extends AbilitySlice {
+
+ /**
+ *
+ */
+ private HarmonyPlayerComponent harmonyPlayerComponent;
+ /**
+ *
+ */
+ private Context context;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ context = this;
+ harmonyPlayerComponent = (HarmonyPlayerComponent) findComponentById(ResourceTable.Id_surface);
+ //添加视频资源
+ harmonyPlayerComponent.setDataSource("http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4");
+ harmonyPlayerComponent.getCoverController().imagePic.setPixelMap(ResourceTable.Media_test);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/element/string.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..4cc335bd2b25277fa79d555980b4fea252e5faf5
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,17 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "HarmonyPlayer"
+ },
+ {
+ "name": "label_name",
+ "value": "HarmonyPlayer"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/graphic/background_ability_main.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/layout/ability_main.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..931afa387e5bdc98cf115a00edd422bf17d783ce
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/media/icon.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/media/icon.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/media/test.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/media/test.png
new file mode 100644
index 0000000000000000000000000000000000000000..43422533809fb1355777ad4f51befa2669130f08
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/entry/src/main/resources/base/media/test.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle.properties b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle/wrapper/gradle-wrapper.jar b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle/wrapper/gradle-wrapper.properties b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradlew b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradlew.bat b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/.gitignore b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/build.gradle b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..115ec9dab4917734bb2e858c3797e205259e0bf5
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile'junit:junit:4.12'
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/config.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..16badd40718f7b57a9d78388143c67dbd7c7d2c5
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/config.json
@@ -0,0 +1,27 @@
+{
+ "app": {
+ "bundleName": "com.example.customview",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5,
+ "releaseType": "Release"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.playerharmonyos",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "playerHarmonyos",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/HarmonyPlayerComponent.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/HarmonyPlayerComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..9295971810abc68a2f79574f9a9f047b299ba90a
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/HarmonyPlayerComponent.java
@@ -0,0 +1,31 @@
+package com.example.playerharmonyos;
+
+import com.example.playerharmonyos.base.BaseVideoPlayer;
+import com.example.playerharmonyos.controller.DefaultCoverController;
+import com.example.playerharmonyos.controller.DefaultGestureController;
+import com.example.playerharmonyos.controller.DefaultVideoController;
+import ohos.agp.components.AttrSet;
+import ohos.agp.window.service.WindowManager;
+import ohos.app.Context;
+
+public class HarmonyPlayerComponent extends BaseVideoPlayer {
+
+ @Override
+ protected int getLayoutID() {
+ return ResourceTable.Layout_video_default_track_layout;
+ }
+
+ public HarmonyPlayerComponent(Context context) {
+ this(context, null);
+ }
+
+ public HarmonyPlayerComponent(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public HarmonyPlayerComponent(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ WindowManager.getInstance().getTopWindow().get().setTransparent(true);
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/HarmonySurfaceProvider.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/HarmonySurfaceProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..da6597548a6f3d702dff1447c49539812dc9d18a
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/HarmonySurfaceProvider.java
@@ -0,0 +1,26 @@
+package com.example.playerharmonyos;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.surfaceprovider.SurfaceProvider;
+import ohos.app.Context;
+
+/**
+ * HarmonySurfaceProvider
+ */
+public class HarmonySurfaceProvider extends SurfaceProvider {
+
+ //目前相关方法找不到 不做任何操作
+
+ public HarmonySurfaceProvider(Context context) {
+ this(context, null);
+ }
+
+ public HarmonySurfaceProvider(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public HarmonySurfaceProvider(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ }
+
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/PlayerPresenter.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/PlayerPresenter.java
new file mode 100644
index 0000000000000000000000000000000000000000..08c7b1dc977fbb985f40ecebc6d54eaea0c2551f
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/PlayerPresenter.java
@@ -0,0 +1,154 @@
+package com.example.playerharmonyos;
+
+import com.example.playerharmonyos.manager.VideoPlayerManager;
+
+public interface PlayerPresenter {
+
+ /**
+ * 设置循环模式
+ *
+ * @param loop true:循环播放 false:反之
+ * @return 代理人
+ */
+ VideoPlayerManager setLoop(boolean loop);
+
+
+ /**
+ * 移动网络工作开关
+ *
+ * @param enable true:允许移动网络工作 false:不允许
+ */
+ void setMobileWorkEnable(boolean enable);
+
+
+ /**
+ * 设置视频画面显示缩放类型
+ *
+ * @param displayType 详见VideoConstants常量定义
+ */
+ void setVideoDisplayType(int displayType);
+
+ /**
+ * 返回播放器内部播放状态
+ *
+ * @return true:正在播放,fasle:未播放
+ */
+ boolean isPlaying();
+
+ /**
+ * 返回播放器内部工作状态
+ *
+ * @return true:正在工作,包含暂停、缓冲等, false:未工作
+ */
+ boolean isWorking();
+
+ /**
+ * 返回当前正在播放的视频宽
+ *
+ * @return 视频宽(分辨率)
+ */
+ int getVideoWidth();
+
+ /**
+ * 返回当前正在播放的视频高
+ *
+ * @return 视频高(分辨率)
+ */
+ int getVideoHeight();
+
+
+ /**
+ * 开始、暂停播放
+ */
+ void playOrPause();
+
+ /**
+ * 恢复播放
+ */
+ void play();
+
+ /**
+ * 暂停播放
+ */
+ void pause();
+
+ /**
+ * 释放、还原播放、监听、渲染等状态
+ */
+ void onReset();
+
+ /**
+ * 停止播放
+ *
+ * @param isReset 是否内部释放播放器
+ */
+ void onStop(boolean isReset);
+
+ /**
+ * 跳转至指定位置播放
+ *
+ * @param currentTime 事件位置,单位毫秒
+ */
+ void seekTo(long currentTime);
+
+ /**
+ * 返回当前播放对象的总时长
+ *
+ * @return 视频总时长,单位毫秒
+ */
+ long getDurtion();
+
+ /**
+ * 返回当前已播放的时长
+ *
+ * @return 已播放的视频长度,单位毫秒
+ */
+ long getCurrentDurtion();
+
+ /**
+ * 是否可以直接返回
+ *
+ * @return true:可以直接返回 false:存在全屏或小窗口
+ */
+ boolean isBackPressed();
+
+ /**
+ * 是否可以直接返回
+ *
+ * @param destroy 是否直接销毁,比如说MainActivity返回逻辑还有询问用户是否退出,给定destroy为false,
+ * 则只是尝试弹射,并不会去销毁播放器
+ * @return true:可以直接返回 false:存在全屏或小窗口
+ */
+ boolean isBackPressed(boolean destroy);
+
+
+ /**
+ * 返回内部播放器播放状态
+ *
+ * @return 内部播放状态,详见VideoConstants.定义
+ */
+ int getVideoPlayerState();
+
+ /**
+ * 此标记标识跳转至目标Activity是否衔接播放
+ *
+ * @param continuePlay true:衔接播放 fasle:不衔接播放
+ */
+ void setContinuePlay(boolean continuePlay);
+
+ /**
+ * 组件对应生命周期调用
+ */
+ void onResume();
+
+ /**
+ * 组件对应生命周期调用
+ */
+ void onPause();
+
+ /**
+ * 组件对应生命周期调用
+ */
+ void onDestroy();
+
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseCoverController.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseCoverController.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1f48e2038549a99da625c2c59e2509f7051a253
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseCoverController.java
@@ -0,0 +1,60 @@
+package com.example.playerharmonyos.base;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.StackLayout;
+import ohos.app.Context;
+
+/**
+ * *封面控制器基类
+ */
+public abstract class BaseCoverController extends StackLayout {
+ public BaseCoverController(Context context) {
+ this(context, null);
+ }
+
+ public BaseCoverController(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public BaseCoverController(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ this.setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ if (null != onStartListener) {
+ onStartListener.onStartPlay();
+ }
+ }
+ });
+ }
+
+ /**
+ *
+ */
+ public interface OnStartListener {
+ /**
+ *
+ */
+ void onStartPlay();
+ }
+
+ /**
+ *
+ */
+ private OnStartListener onStartListener;
+
+ public void setOnStartListener(OnStartListener onStartListener) {
+ /**
+ *
+ */
+ this.onStartListener = onStartListener;
+ }
+
+ public void onDestroy() {
+ /**
+ *
+ */
+ onStartListener = null;
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseGestureController.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseGestureController.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a5fc9e3544382f7607a60b25a0616fb835041a2
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseGestureController.java
@@ -0,0 +1,114 @@
+package com.example.playerharmonyos.base;
+
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.StackLayout;
+import ohos.app.Context;
+import ohos.multimodalinput.event.TouchEvent;
+
+public abstract class BaseGestureController extends StackLayout {
+
+ /**
+ * //改变播放进度
+ */
+ public static final int SCENE_PROGRESS = 1;
+ /**
+ * //改变屏幕亮度
+ */
+ public static final int SCENE_BRIGHTNRSS = 2;
+ /**
+ * //改变声音大小
+ */
+ public static final int SCENE_SOUND = 3;
+
+ /**
+ * 手势持续滚动的方向
+ */
+ /**
+ * //持续向左滑动
+ */
+ public static final int SCROLL_ORIENTATION_LEFT = 0;
+ /**
+ * //持续向上滑动
+ */
+ public static final int SCROLL_ORIENTATION_TOP = 1;
+ /**
+ * //持续向右滑动
+ */
+ public static final int SCROLL_ORIENTATION_RIGHT = 2;
+ /**
+ * //持续向下滑动
+ */
+ public static final int SCROLL_ORIENTATION_BUTTOM = 3;
+
+ public BaseGestureController(Context context) {
+ this(context, null);
+ }
+
+ public BaseGestureController(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public BaseGestureController(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ }
+
+ /**
+ * 更新场景
+ *
+ * @param gestureScene 场景模式,详见此类常量定义说明
+ */
+ public abstract void updataGestureScene(int gestureScene);
+
+ /**
+ * 更新播放进度显示
+ *
+ * @param totalTime 视频总时长
+ * @param speedTime 目标seek时长位置
+ * @param progress 转换后的progress,单位百分比
+ */
+ public abstract void setVideoProgress(long totalTime, long speedTime, int progress);
+
+ /**
+ * 设置音量百分比进度
+ *
+ * @param progress 百分比
+ */
+ public abstract void setSoundrogress(int progress);
+
+
+ /**
+ * 设置亮度百分比进度
+ *
+ * @param progress 百分比
+ */
+ public abstract void setBrightnessProgress(int progress);
+
+ /**
+ * 手势事件,当其他四个主要更新UI方法无法满足你的场景时,你应该关心这个方法,如果不允许BaseVideoPlayer
+ * 处理手势事件,则返回true:即拦截事件向BaseVideoPlayer传递
+ *
+ * @param e1 13123
+ * @param e2 3123
+ * @param distanceX 123123
+ * @param distanceY 13123
+ * @return 为true则表示消费触摸事件并拦截事件继续向BaseVideoPlayer传递
+ */
+ public abstract boolean onTouchEnevt(TouchEvent e1, TouchEvent e2, float distanceX, float distanceY);
+
+ /**
+ * 复原
+ */
+ public abstract void onReset();
+
+ /**
+ * 复原
+ *
+ * @param delayedMilliss 完全不可见的延时
+ */
+ public abstract void onReset(long delayedMilliss);
+
+ /**
+ * 销毁
+ */
+ public abstract void onDestroy();
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseVideoController.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseVideoController.java
new file mode 100644
index 0000000000000000000000000000000000000000..97b793ec721488231652174724fd998a8212dc67
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseVideoController.java
@@ -0,0 +1,240 @@
+package com.example.playerharmonyos.base;
+
+import com.example.playerharmonyos.constant.VideoConstants;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.StackLayout;
+import ohos.app.Context;
+
+public abstract class BaseVideoController extends StackLayout {
+
+ /**
+ *
+ */
+ protected int scrrenOrientation = VideoConstants.SCREEN_ORIENTATION_PORTRAIT;
+
+ public BaseVideoController(Context context) {
+ this(context, null);
+ }
+
+ public BaseVideoController(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public BaseVideoController(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ }
+
+
+ /**
+ *
+ */
+ public interface OnStartListener {
+ void onStartPlay();
+ }
+
+
+ /**
+ *
+ */
+ protected OnStartListener onStartListener;
+
+
+ /**
+ *
+ */
+ public void setOnStartListener(OnStartListener onStartListener) {
+ this.onStartListener = onStartListener;
+ }
+
+
+ /**
+ * 标准的必须实现关心的方法
+ */
+
+ /**
+ * //准备播放中
+ */
+ public abstract void readyPlaying();
+
+
+ /**
+ * //开始缓冲中
+ */
+ public abstract void startBuffer();
+
+
+ /**
+ * //缓冲结束
+ */
+ public abstract void endBuffer();
+
+ /**
+ * //开始播放中
+ */
+
+ public abstract void play();
+
+ /**
+ * //已暂停播放
+ */
+
+ public abstract void pause();
+
+ /**
+ *
+ */
+ public abstract void repeatPlay();
+
+ /**
+ * //移动网络状态下工作
+ */
+
+ public abstract void mobileWorkTips();
+
+ /**
+ * 播放失败
+ *
+ * @param errorCode 错误码
+ * @param errorMessage 错误日志
+ */
+ public abstract void error(int errorCode, String errorMessage);
+
+
+ /**
+ * //播放器被重置
+ */
+ public abstract void reset();
+
+ /**
+ * 开始跳转播放
+ */
+ protected void startSeek() {
+ }
+
+ /**
+ * 视频总长度、 播放进度、缓冲进度
+ *
+ * @param totalDurtion 视频总长度 单位:毫秒,暂停下为-1
+ * @param currentDurtion 播放进度 单位:毫秒,暂停下为-1
+ * @param bufferPercent 缓冲进度,单位:百分比
+ */
+ protected void onTaskRuntime(long totalDurtion, long currentDurtion, int bufferPercent) {
+ }
+
+ /**
+ * 播放器内部实时播放进度,只会在子线程被调用,请注意
+ *
+ * @param totalPosition 总视频时长,单位:毫秒
+ * @param currentPosition 实施播放进度,单位:毫秒
+ * @param bufferPercent 缓冲进度,单位:百分比
+ */
+ protected void currentPosition(long totalPosition, long currentPosition, int bufferPercent) {
+ }
+
+ /**
+ * 缓冲百分比
+ *
+ * @param percent 实时缓冲进度,单位:百分比
+ */
+ protected void onBufferingUpdate(int percent) {
+ }
+
+ /**
+ * 播放器空白位置单击事件,关注此方法实现控制器的现实和隐藏
+ *
+ * @param scrrenOrientation 当前的窗口方向
+ * @param isInterceptIntent 为true:用户主动点击
+ */
+ protected void changeControllerState(int scrrenOrientation, boolean isInterceptIntent) {
+ }
+
+ /**
+ * 更新屏幕方向
+ *
+ * @param scrrenOrientation 1:竖屏,>1:横屏
+ */
+ public void setScrrenOrientation(int scrrenOrientation) {
+ this.scrrenOrientation = scrrenOrientation;
+ }
+
+ /**
+ * 切换为竖屏方向
+ */
+ protected void startHorizontal() {
+ }
+
+
+ /**
+ *
+ */
+ public abstract static class OnFuctionListener {
+ /**
+ * 开启全屏
+ *
+ * @param videoController 继承自BaseVideoController的自定义控制器
+ */
+ public void onStartFullScreen(BaseVideoController videoController) {
+ }
+
+ /**
+ * 开启迷你窗口
+ *
+ * @param miniWindowController 继承自BaseVideoController的自定义控制器
+ */
+ public void onStartMiniWindow(BaseVideoController miniWindowController) {
+ }
+
+ /**
+ * 开启全局悬浮窗
+ *
+ * @param windowController 继承自BaseVideoController的自定义控制器
+ * @param defaultCreatCloseIcon 是否创建一个默认的关闭按钮,位于悬浮窗右上角,若允许创建,
+ * 则播放器内部消化关闭时间
+ */
+ public void onStartGlobalWindown(BaseVideoController windowController, boolean defaultCreatCloseIcon) {
+ }
+
+ /**
+ * //关闭迷你窗口
+ */
+
+ public void onQuiteMiniWindow() {
+ }
+
+
+ /**
+ * //打开播放器界面
+ */
+
+ public void onStartActivity() {
+ }
+
+ /**
+ * //弹射返回
+ */
+ public void onBackPressed() {
+ }
+ }
+
+
+ /**
+ *
+ */
+ protected OnFuctionListener onFuctionListener;
+
+
+ /**
+ *
+ */
+ public void setOnFuctionListener(OnFuctionListener onFuctionListener) {
+ this.onFuctionListener = onFuctionListener;
+ }
+
+
+ /**
+ *
+ */
+ protected void onDestroy() {
+ onFuctionListener = null;
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseVideoPlayer.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseVideoPlayer.java
new file mode 100644
index 0000000000000000000000000000000000000000..76af551b20f97eaf1883d0530be97c1d757bfb46
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/BaseVideoPlayer.java
@@ -0,0 +1,563 @@
+package com.example.playerharmonyos.base;
+
+import com.example.playerharmonyos.HarmonySurfaceProvider;
+import com.example.playerharmonyos.ResourceTable;
+import com.example.playerharmonyos.constant.VideoConstants;
+import com.example.playerharmonyos.controller.DefaultCoverController;
+import com.example.playerharmonyos.controller.DefaultVideoController;
+import com.example.playerharmonyos.listener.PlayerEventListener;
+import com.example.playerharmonyos.manager.VideoPlayerManager;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.StackLayout;
+import ohos.agp.components.ComponentContainer;
+import ohos.agp.utils.LayoutAlignment;
+import ohos.app.Context;
+import ohos.multimodalinput.event.TouchEvent;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * @param 123
+ * @param 123
+ * @param 123
+ */
+public abstract class BaseVideoPlayer
+ extends StackLayout implements PlayerEventListener
+ , Component.TouchEventListener {
+ /**
+ *
+ */
+ private V videoController;
+ /**
+ *
+ */
+ private C coverController;
+ /**
+ *
+ */
+ private G gestureController;
+ /**
+ * //资源地址、视频标题
+ */
+ private String dataSource;
+ /**
+ * //视频帧渲染父容器
+ */
+ private StackLayout surfaceView;
+ /**
+ *
+ */
+ private StackLayout videoPlayerController;
+ /**
+ *
+ */
+ private StackLayout videoCoverController;
+ /**
+ *
+ */
+ private Context context;
+ /**
+ * //屏幕方向、手势调节,默认未知
+ */
+ private int screenORIENTATION = 0;
+ /**
+ * //此播放器是否正在工作,配合列表滚动时,检测工作状态
+ */
+ private boolean isPlayerWorking = false;
+
+
+ /**
+ *
+ */
+ protected abstract int getLayoutID();
+
+ public BaseVideoPlayer(Context context) {
+ this(context, null);
+ }
+
+ public BaseVideoPlayer(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public BaseVideoPlayer(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ boolean autoSetVideoController = false;
+ boolean autoSetCoverController = false;
+ this.context = context;
+ Component component = LayoutScatter.getInstance(context).parse(getLayoutID(), null, false);
+ addComponent(component);
+ surfaceView = (StackLayout) findComponentById(ResourceTable.Id_surface_view);
+ videoPlayerController = (StackLayout) findComponentById(ResourceTable.Id_video_player_controller);
+ videoCoverController = (StackLayout) findComponentById(ResourceTable.Id_video_cover_controller);
+
+ setVideoController(null, true);
+ setCoverController(null, true);
+// setGestureController(null);
+ if (surfaceView != null) {
+// surfaceView.setTouchEventListener(this::onTouchEvent);
+ surfaceView.setClickedListener(component1 -> {
+ if (VideoPlayerManager.getInstance().isPlaying()) {
+ if (null != videoController) {
+ videoController.changeControllerState(screenORIENTATION, true);
+ }
+ }
+ });
+ }
+ }
+
+
+ /**
+ *
+ */
+ private void setGestureController(V fullScreenVideoController) {
+ try {
+ IPlayer.getInstance().setNoimalPlayer(BaseVideoPlayer.this);
+ Constructor extends BaseVideoPlayer> constructor =
+ BaseVideoPlayer.this.getClass().getConstructor(Context.class);
+ BaseVideoPlayer videoPlayer = constructor.newInstance(getContext());
+ IPlayer.getInstance().setFullScrrenPlayer(videoPlayer);
+// addTextrueViewToView(videoPlayer);
+ //添加监听器
+ IPlayer.getInstance().addOnPlayerEventListener(videoPlayer);
+ //手动检查播放器内部状态,同步常规播放器状态至新的播放器
+ IPlayer.getInstance().checkedVidepPlayerState();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ *
+ */
+ private void setCoverController(C coverController, boolean autoCreateDefault) {
+ if (videoCoverController != null) {
+ this.coverController = (C) new DefaultCoverController(context);
+
+ this.coverController.setOnStartListener(() -> {
+ startPlayVideo();
+ });
+
+ videoCoverController.addComponent(this.coverController, new LayoutConfig(LayoutConfig.MATCH_PARENT,
+ LayoutConfig.MATCH_PARENT, LayoutAlignment.CENTER));
+ }
+ }
+
+
+ /**
+ *
+ */
+ public void setVideoController(V videoController, boolean autoCreateDefault) {
+ if (videoPlayerController != null) {
+ removeGroupView(this.videoController);
+ if (videoPlayerController.getChildCount() > 0) {
+ videoPlayerController.removeAllComponents();
+ }
+ if (null != this.videoController) {
+ this.videoController.onDestroy();
+ this.videoController = null;
+ }
+ if (null != this.videoController) {
+ this.videoController = videoController;
+ } else {
+ //是否使用默认的
+ if (autoCreateDefault) {
+ this.videoController = (V) new DefaultVideoController(getContext());
+ }
+ }
+ //添加控制器到播放器
+ if (null != this.videoController) {
+ this.videoController.setOnStartListener(() -> {
+ if (IPlayer.getInstance().getVideoPlayerState() == VideoConstants.MUSIC_PLAYER_STOP) {
+ startPlayVideo();
+ } else {
+ IPlayer.getInstance().playOrPause();
+ }
+ });
+
+ this.videoController.setOnFuctionListener(new BaseVideoController.OnFuctionListener() {
+ @Override
+ public void onStartFullScreen(BaseVideoController videoController) {
+ if (screenORIENTATION == VideoConstants.SCREEN_ORIENTATION_PORTRAIT) {
+ setGestureController((V) videoController);
+ } else {
+// backFullScreenWindow();
+ }
+ }
+
+ @Override
+ public void onStartMiniWindow(BaseVideoController miniWindowController) {
+ super.onStartMiniWindow(miniWindowController);
+ }
+
+ @Override
+ public void onStartGlobalWindown(BaseVideoController windowController, boolean defaultCreatCloseIcon) {
+ super.onStartGlobalWindown(windowController, defaultCreatCloseIcon);
+ }
+
+ @Override
+ public void onQuiteMiniWindow() {
+ super.onQuiteMiniWindow();
+ }
+
+ @Override
+ public void onStartActivity() {
+ super.onStartActivity();
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ }
+ });
+ }
+
+ videoPlayerController.addComponent(this.videoController, new LayoutConfig(LayoutConfig.MATCH_PARENT,
+ LayoutConfig.MATCH_PARENT, LayoutAlignment.CENTER));
+ }
+ }
+
+ /**
+ * 将自己从父Parent中移除
+ *
+ * @param viewGroup view
+ */
+ private void removeGroupView(ComponentContainer viewGroup) {
+ if (null != viewGroup && null != viewGroup.getComponentParent()) {
+ ComponentContainer parent = (ComponentContainer) viewGroup.getComponentParent();
+ parent.removeComponent(viewGroup);
+ }
+ }
+
+ /**
+ * 设置播放资源
+ *
+ * @param path 暂支持file、http、https等协议
+ */
+ public void setDataSource(String path) {
+ this.dataSource = path;
+ }
+
+ /**
+ * 开始播放的入口开始播放、准备入口
+ */
+ public void startPlayVideo() {
+ if (dataSource.isEmpty()) {
+ return;
+ }
+ //还原可能正在进行的播放任务
+ IPlayer.getInstance().onReset();
+ IPlayer.getInstance().addOnPlayerEventListener(this);
+ //准备画面渲染图层
+ if (null != surfaceView) {
+ addTextrueViewToView(BaseVideoPlayer.this);
+ //开始准备播放
+ IPlayer.getInstance().startVideoPlayer(dataSource, getContext());
+ }
+ }
+
+ private void addTextrueViewToView(BaseVideoPlayer videoPlayer) {
+ //先移除存在的harmonySurfaceProvider
+ if (null != IPlayer.getInstance().getHarmonySurfaceProvider()) {
+ HarmonySurfaceProvider harmonySurfaceProvider = IPlayer.getInstance().getHarmonySurfaceProvider();
+ if (null != harmonySurfaceProvider.getComponentParent()) {
+ (harmonySurfaceProvider.getComponentParent()).removeComponent(harmonySurfaceProvider);
+ }
+ }
+ if (null == videoPlayer.surfaceView) return;
+ if (null != IPlayer.getInstance().getHarmonySurfaceProvider()) {
+ videoPlayer.surfaceView.addComponent(IPlayer.getInstance().getHarmonySurfaceProvider(), new LayoutConfig(LayoutConfig.MATCH_PARENT,
+ LayoutConfig.MATCH_PARENT, LayoutAlignment.CENTER));
+
+ } else {
+ HarmonySurfaceProvider harmonySurfaceProvider = new HarmonySurfaceProvider(context);
+ IPlayer.getInstance().initHarmonySurfaceProvider(harmonySurfaceProvider);
+ videoPlayer.surfaceView.addComponent(harmonySurfaceProvider, new LayoutConfig(LayoutConfig.MATCH_PARENT,
+ LayoutConfig.MATCH_PARENT, LayoutAlignment.CENTER));
+ }
+ }
+
+ /**
+ * 此处返回此组件绑定的工作状态
+ *
+ * @return true:正在工作 false反之
+ */
+ public boolean isPlayerWorking() {
+ return isPlayerWorking;
+ }
+
+
+ /**
+ *
+ */
+ public void setPlayerWorking(boolean playerWorking) {
+ isPlayerWorking = playerWorking;
+ }
+
+ /**
+ * 播放器内部状态变化
+ *
+ * @param playerState 播放器内部状态
+ * @param message 状态描述
+ */
+ @Override
+ public void onVideoPlayerState(int playerState, String message) {
+ context.getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ switch (playerState) {
+ //已结束,或未开始
+ case VideoConstants.MUSIC_PLAYER_STOP:
+ if (null != coverController && coverController.getVisibility() != VISIBLE) {
+ coverController.setVisibility(VISIBLE);
+ }
+ if (null != videoController) {
+ videoController.reset();
+ }
+ break;
+ //准备中
+ case VideoConstants.MUSIC_PLAYER_PREPARE:
+ if (null != coverController && coverController.getVisibility() != VISIBLE) {
+ coverController.setVisibility(VISIBLE);
+ }
+ if (null != videoController) {
+ videoController.readyPlaying();
+ }
+ break;
+ //播放过程缓冲中
+ case VideoConstants.MUSIC_PLAYER_BUFFER:
+ if (null != coverController && coverController.getVisibility() != HIDE) {
+ coverController.setVisibility(HIDE);
+ }
+ if (null != videoController) {
+ videoController.startBuffer();
+ }
+ break;
+ //播放中
+ case VideoConstants.MUSIC_PLAYER_START:
+ if (null != coverController && coverController.getVisibility() != HIDE) {
+ coverController.setVisibility(HIDE);
+ }
+ if (null != videoController) {
+ videoController.play();
+ }
+ break;
+ //暂停
+ case VideoConstants.MUSIC_PLAYER_PAUSE:
+ if (null != coverController && coverController.getVisibility() != HIDE) {
+ coverController.setVisibility(HIDE);
+ }
+ if (null != videoController) {
+ videoController.pause();
+ }
+ break;
+ //恢复播放
+ case VideoConstants.MUSIC_PLAYER_PLAY:
+ if (null != videoController) {
+ videoController.repeatPlay();
+ }
+ break;
+ //开始跳转播放中
+ case VideoConstants.MUSIC_PLAYER_SEEK:
+ if (null != videoController) {
+ videoController.startSeek();
+ }
+ break;
+ //移动网络环境下
+ case VideoConstants.MUSIC_PLAYER_MOBILE:
+ break;
+ //错误
+ case VideoConstants.MUSIC_PLAYER_ERROR:
+ break;
+ }
+ }
+ });
+ }
+
+
+ /**
+ *
+ */
+ @Override
+ public void onPrepared(long totalDurtion) {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void onBufferingUpdate(int percent) {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void onInfo(int event, int extra) {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void onVideoPathInvalid() {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void onTaskRuntime(long totalDurtion, long currentDurtion, int bufferPercent) {
+ context.getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ if (videoController != null) {
+ videoController.onTaskRuntime(totalDurtion, currentDurtion, bufferPercent);
+ }
+ }
+ });
+ }
+
+ /**
+ *
+ */
+ public C getCoverController() {
+ return coverController;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void currentPosition(long totalPosition, long currentPosition, int bufferPercent) {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void onDestroy() {
+
+ }
+
+ /**
+ *
+ */
+ private float moveDistanceX = 0;
+
+ /**
+ *
+ */
+ private float moveDistanceY = 0;
+ /**
+ *
+ */
+
+ private float moveX = 0;
+
+ /**
+ *
+ */
+ private float moveY = 0;
+
+ /**
+ *
+ */
+
+ @Override
+ public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
+ final boolean pointerUp =
+ touchEvent.getAction() == TouchEvent.OTHER_POINT_UP;
+ final int skipIndex = pointerUp ? touchEvent.getIndex() : -1;
+ float sumX = 0;
+ float sumY = 0;
+ final int count = touchEvent.getPointerCount();
+ // 把所有还在触摸的手指的位置x,y加起来,后面求平均数,算出中心焦点
+ for (int i = 0; i < count; i++) {
+ if (skipIndex == i) {
+ // 跳过非主要指针的抬起动作
+ continue;
+ }
+ sumX += touchEvent.getPointerPosition(i).getX();
+ sumY += touchEvent.getPointerPosition(i).getY();
+ }
+ final int div = pointerUp ? count - 1 : count;
+ // 求平均值,算出中心焦点
+ float endUpX = sumX / div;
+ float endUpY = sumY / div;
+
+ switch (touchEvent.getAction()) {
+ case TouchEvent.CANCEL:
+ System.out.println("-------指示事件被中断或取消。。-------");
+ break;
+ case TouchEvent.PRIMARY_POINT_UP:
+ break;
+ case TouchEvent.PRIMARY_POINT_DOWN:
+ //表示第一根手指触摸屏幕。
+ moveDistanceX = moveX = endUpX;
+ moveDistanceY = moveY = endUpY;
+ break;
+ case TouchEvent.POINT_MOVE:
+ float scrollX = endUpX - moveX;
+ float scrollY = endUpY - moveY;
+ //手指移动距离 x >=y 横向滑动 x= Math.abs(scrollY)) {
+ System.out.println("横向滑动==========");
+ } else {
+ System.out.println("上下滑动==========");
+ }
+ moveX = endUpX;
+ moveY = endUpY;
+
+// gestureController.updataGestureScene(GESTURE_SCENE);
+
+
+ break;
+
+ default:
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * 更新播放器方向
+ *
+ * @param scrrenOrientation 详见 VideoConstants 常量定义
+ */
+ public void setScrrenOrientation(int scrrenOrientation) {
+ this.screenORIENTATION = scrrenOrientation;
+ if (null != videoController) {
+ videoController.setScrrenOrientation(scrrenOrientation);
+ }
+ }
+
+ /**
+ * 仅释放播放器窗口UI
+ */
+ public void reset() {
+ //先移除存在的TextrueView
+ if (null != IPlayer.getInstance().getHarmonySurfaceProvider()) {
+ HarmonySurfaceProvider textureView = IPlayer.getInstance().getHarmonySurfaceProvider();
+ if (null != textureView.getComponentParent()) {
+ textureView.getComponentParent().removeComponent(textureView);
+ }
+ }
+ if (null != videoController) {
+ videoController.reset();
+ }
+ if (null != coverController) {
+ coverController.setVisibility(VISIBLE);
+ }
+// setPlayerWorking(false);
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/IPlayer.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/IPlayer.java
new file mode 100644
index 0000000000000000000000000000000000000000..5219a740519438652b955066b25dfb9ec2ba74ba
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/base/IPlayer.java
@@ -0,0 +1,529 @@
+package com.example.playerharmonyos.base;
+
+import com.example.playerharmonyos.HarmonySurfaceProvider;
+import com.example.playerharmonyos.PlayerPresenter;
+import com.example.playerharmonyos.constant.VideoConstants;
+import com.example.playerharmonyos.listener.PlayerEventListener;
+import com.example.playerharmonyos.manager.VideoPlayerManager;
+import ohos.agp.graphics.Surface;
+import ohos.agp.graphics.SurfaceOps;
+import ohos.app.Context;
+import ohos.media.common.Source;
+import ohos.media.player.Player;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+public final class IPlayer implements PlayerPresenter {
+ /**
+ * |
+ */
+ private static volatile IPlayer MYPLAYER;
+ /**
+ *
+ */
+ private Context context;
+ /**
+ *
+ */
+ private Player player;
+ /**
+ *
+ */
+ private HarmonySurfaceProvider harmonySurfaceProvider;
+ /**
+ *
+ */
+ private Surface surface;
+ /**
+ * //播放源
+ */
+ private String dataSource;
+ /**
+ * //播放器组件监听器
+ */
+ private PlayerEventListener onPlayerEventListeners;
+ /**
+ * //内部播放状态
+ */
+ private int musicPlayerState = VideoConstants.MUSIC_PLAYER_STOP;
+ /**
+ * //进度计时器
+ */
+ private PlayTimerTask playTimerTask;
+ /**
+ *
+ */
+ private Timer timer;
+ /**
+ * //实时播放位置
+ */
+ private int percentIndex;
+ /**
+ * //缓冲进度
+ */
+ private int bufferPercent;
+ /**
+ *
+ */
+ private BaseVideoPlayer noimalPlayer;
+ /**
+ * //TASK执行次数计时
+ */
+ private long timerRunCount = 0;
+
+ public static IPlayer getInstance() {
+ if (null == MYPLAYER) {
+ synchronized (IPlayer.class) {
+ if (null == MYPLAYER) {
+ MYPLAYER = new IPlayer();
+ }
+ }
+ }
+ return MYPLAYER;
+ }
+
+ private IPlayer() {
+ VideoPlayerManager.getInstance().setIMediaPlayer(this);
+ }
+
+ /**
+ * @param loop true:循环播放 false:反之
+ * @return 管理类的回调
+ */
+
+ @Override
+ public VideoPlayerManager setLoop(boolean loop) {
+ if (null != player) {
+ player.enableSingleLooping(loop);
+ }
+ return VideoPlayerManager.getInstance();
+ }
+
+ @Override
+ public void setMobileWorkEnable(boolean enable) {
+
+ }
+
+ @Override
+ public void setVideoDisplayType(int displayType) {
+
+ }
+
+ @Override
+ public boolean isPlaying() {
+ return null != player && (musicPlayerState == VideoConstants.MUSIC_PLAYER_PLAY
+ || musicPlayerState == VideoConstants.MUSIC_PLAYER_START);
+ }
+
+ @Override
+ public boolean isWorking() {
+ return false;
+ }
+
+ @Override
+ public int getVideoWidth() {
+ return 0;
+ }
+
+ @Override
+ public int getVideoHeight() {
+ return 0;
+ }
+
+ @Override
+ public void playOrPause() {
+ switch (getVideoPlayerState()) {
+ case VideoConstants.MUSIC_PLAYER_STOP:
+ startVideoPlayer(dataSource, context);
+ break;
+ case VideoConstants.MUSIC_PLAYER_PREPARE:
+ pause();
+ break;
+ case VideoConstants.MUSIC_PLAYER_START:
+ pause();
+ break;
+ case VideoConstants.MUSIC_PLAYER_PAUSE:
+ play();
+ break;
+ case VideoConstants.MUSIC_PLAYER_PLAY:
+ pause();
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void play() {
+ try {
+ if (null != player) {
+ player.play();
+ }
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ } finally {
+ if (null != player) {
+ musicPlayerState = VideoConstants.MUSIC_PLAYER_PLAY;
+ if (null != onPlayerEventListeners) {
+ onPlayerEventListeners.onVideoPlayerState(musicPlayerState, null);
+ }
+ startTimer();
+ }
+ }
+ }
+
+ @Override
+ public void pause() {
+ try {
+ if (null != player && player.isNowPlaying()) {
+ player.pause();
+ }
+ } catch (RuntimeException e) {
+
+ } finally {
+ stopTimer();
+ musicPlayerState = VideoConstants.MUSIC_PLAYER_PAUSE;
+ if (null != onPlayerEventListeners) {
+ onPlayerEventListeners.onVideoPlayerState(musicPlayerState, null);
+ }
+ }
+ }
+
+ @Override
+ public void onReset() {
+
+ }
+
+ @Override
+ public void onStop(boolean isReset) {
+
+ }
+
+ @Override
+ public void seekTo(long currentTime) {
+ try {
+ if (null != player) {
+ player.rewindTo(currentTime);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public long getDurtion() {
+ try {
+ if (null != player) {
+ return player.getDuration();
+ }
+ } catch (RuntimeException e) {
+
+ }
+ return 0;
+ }
+
+ @Override
+ public long getCurrentDurtion() {
+ return 0;
+ }
+
+ @Override
+ public boolean isBackPressed() {
+ return false;
+ }
+
+ @Override
+ public boolean isBackPressed(boolean destroy) {
+ return false;
+ }
+
+ @Override
+ public int getVideoPlayerState() {
+ return musicPlayerState;
+ }
+
+ @Override
+ public void setContinuePlay(boolean continuePlay) {
+
+ }
+
+ @Override
+ public void onResume() {
+
+ }
+
+ @Override
+ public void onPause() {
+
+ }
+
+ @Override
+ public void onDestroy() {
+
+ }
+
+ private class VideoSurfaceCallback implements SurfaceOps.Callback {
+ //surface相关回调
+ @Override
+ public void surfaceCreated(SurfaceOps surfaceOps) {
+ if (harmonySurfaceProvider.getSurfaceOps().isPresent()) {
+ surface = harmonySurfaceProvider.getSurfaceOps().get().getSurface();
+ player = new Player(context);
+ Source source = new Source(dataSource);
+ player.setSource(source);
+ player.setPlayerCallback(new PlayerCall());
+ player.setVideoSurface(surface);
+ player.prepare();
+ System.out.println("准备播放=========");
+ }
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {
+// surfaceOps.setFixedSize();
+
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceOps surfaceOps) {
+ }
+ }
+
+ class PlayerCall implements Player.IPlayerCallback {
+
+ //播放器相关回调
+ @Override
+ public void onPrepared() {
+ System.out.println("11111开始播放=========");
+ if (surface != null) {
+ System.out.println("开始播放=========");
+ player.play();
+ }
+ musicPlayerState = VideoConstants.MUSIC_PLAYER_START;
+ if (null != onPlayerEventListeners) {
+ onPlayerEventListeners.onVideoPlayerState(musicPlayerState, null);
+ }
+ }
+
+ @Override
+ public void onMessage(int i, int i1) {
+ System.out.println("onMessage=======" + i);
+ }
+
+ @Override
+ public void onError(int i, int i1) {
+ System.out.println("onError=======" + i);
+ }
+
+ @Override
+ public void onResolutionChanged(int i, int i1) {
+
+ }
+
+ @Override
+ public void onPlayBackComplete() {
+ musicPlayerState = VideoConstants.MUSIC_PLAYER_STOP;
+ stopTimer();
+ if (null != onPlayerEventListeners) {
+ onPlayerEventListeners.onVideoPlayerState(musicPlayerState, null);
+ }
+ }
+
+ @Override
+ public void onRewindToComplete() {
+
+ }
+
+ @Override
+ public void onBufferingChange(int i) {
+// System.out.println("自定义onBufferingChange=======" + i);
+ bufferPercent = i;
+ if (null != onPlayerEventListeners) {
+ onPlayerEventListeners.onBufferingUpdate(i);
+ }
+ }
+
+ @Override
+ public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {
+
+ }
+
+ @Override
+ public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {
+
+ }
+ }
+
+ private class PlayTimerTask extends TimerTask {
+ @Override
+ public void run() {
+ timerRunCount++;
+ if (timerRunCount % 10 == 0) {
+ if (null != onPlayerEventListeners) {
+ if (null != player && player.isNowPlaying()) {
+ //+500毫秒是因为1秒一次的播放进度回显,格式化分秒后显示有时候到不了终点时间
+ onPlayerEventListeners.onTaskRuntime(player.getDuration(),
+ player.getCurrentTime() + 500, bufferPercent);
+ } else {
+ onPlayerEventListeners.onTaskRuntime(-1, -1, bufferPercent);
+ }
+ }
+ }
+
+ }
+ }
+
+ /**
+ * 开始异步准备缓冲播放
+ *
+ * @param dataSource 播放资源地址,支持file、https、http 等协议
+ * @param context 全局上下文
+ */
+ public void startVideoPlayer(String dataSource, Context context) {
+
+ startVideoPlayer(dataSource, context, 0);
+ }
+
+ /**
+ * 开始异步准备缓冲播放
+ *
+ * @param dataSource 播放资源地址,支持file、https、http 等协议
+ * @param context 全局上下文
+ * @param percentIndex 尝试从指定位置开始播放
+ */
+ private void startVideoPlayer(String dataSource, Context context, int percentIndex) {
+ this.context = context;
+ if (dataSource.isEmpty()) {
+ return;
+ }
+ if (IPlayer.this.musicPlayerState == VideoConstants.MUSIC_PLAYER_PREPARE
+ && dataSource.equals(dataSource)) {
+ return;
+ }
+ this.percentIndex = percentIndex;
+ this.dataSource = dataSource;
+
+ startTimer();
+ IPlayer.this.musicPlayerState = VideoConstants.MUSIC_PLAYER_PREPARE;
+
+ if (null != onPlayerEventListeners) {
+ onPlayerEventListeners.onVideoPlayerState(musicPlayerState, "播放准备中");
+ }
+ }
+
+ /**
+ * 开始计时任务
+ */
+ private void startTimer() {
+ if (null == playTimerTask) {
+ timer = new Timer();
+ playTimerTask = new PlayTimerTask();
+ timer.schedule(playTimerTask, 0, 100);
+ }
+ }
+
+ /**
+ * 结束计时任务
+ */
+ private void stopTimer() {
+ if (null != playTimerTask) {
+ playTimerTask.cancel();
+ playTimerTask = null;
+ }
+ if (null != timer) {
+ timer.cancel();
+ timer = null;
+ }
+ timerRunCount = 0;
+ }
+
+
+ /**
+ * 注册播放器工作状态监听器
+ *
+ * @param listener 实现VideoPlayerEventListener的对象
+ */
+ public void addOnPlayerEventListener(PlayerEventListener listener) {
+ this.onPlayerEventListeners = listener;
+ }
+
+ /**
+ * 返回承载画面渲染器
+ *
+ * @return textureView
+ */
+ public HarmonySurfaceProvider getHarmonySurfaceProvider() {
+ return this.harmonySurfaceProvider;
+ }
+
+ /**
+ * 保存全屏窗口播放器
+ *
+ * @param videoPlayer 播放器实例
+ */
+ public void setFullScrrenPlayer(BaseVideoPlayer videoPlayer) {
+ }
+
+ /**
+ * 画面渲染图层初始化
+ *
+ * @param textureView 自定义画面渲染器
+ */
+ public void initHarmonySurfaceProvider(HarmonySurfaceProvider textureView) {
+ this.harmonySurfaceProvider = textureView;
+ this.harmonySurfaceProvider.getSurfaceOps().get().addCallback(new VideoSurfaceCallback());
+ this.harmonySurfaceProvider.pinToZTop(false);
+ }
+
+ /**
+ * 检查播放器内部状态
+ */
+ public void checkedVidepPlayerState() {
+ if (null != onPlayerEventListeners) {
+ onPlayerEventListeners.onVideoPlayerState(musicPlayerState, null);
+ }
+ }
+
+ /**
+ * 保存常规播放器
+ *
+ * @param videoPlayer 播放器实例
+ */
+ public void setNoimalPlayer(BaseVideoPlayer videoPlayer) {
+ this.noimalPlayer = videoPlayer;
+ }
+
+ /**
+ * 返回常规播放器实例
+ *
+ * @return 播放器实例
+ */
+ public BaseVideoPlayer getNoimalPlayer() {
+ return this.noimalPlayer;
+ }
+
+
+ /**
+ * 只是释放播放器
+ */
+ private void reset() {
+ try {
+ if (null != player) {
+ if (player.isNowPlaying()) {
+ player.stop();
+ }
+ player.reset();
+ player.release();
+ player = null;
+ }
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ } finally {
+ bufferPercent = 0;
+// if(null!=mAudioFocusManager){
+// mAudioFocusManager.releaseAudioFocus();
+// }
+ }
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/constant/VideoConstants.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/constant/VideoConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..0807008581059ec45d44fdf2402e98e444771f0b
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/constant/VideoConstants.java
@@ -0,0 +1,74 @@
+package com.example.playerharmonyos.constant;
+
+public interface VideoConstants {
+ /**
+ * 常规
+ */
+ int SCREEN_ORIENTATION_PORTRAIT = 0;
+ /**
+ * 全屏
+ */
+ int SCREEN_ORIENTATION_FULL = 1;
+ /**
+ * 小窗口
+ */
+ int SCREEN_ORIENTATION_TINY = 2;
+ /**
+ * 悬浮窗口
+ */
+ int SCREEN_ORIENTATION_WINDOW = 3;
+
+ /**
+ * 缩放至控件宽高,会裁剪超出比例的画面
+ */
+ int VIDEO_DISPLAY_TYPE_CUT = 0;
+ /**
+ * 铺满延申至全屏,可能会有画面变形
+ */
+ int VIDEO_DISPLAY_TYPE_PARENT = 1;
+ /**
+ * 原始大小居中显示,不做任何裁剪和缩放
+ */
+ int VIDEO_DISPLAY_TYPE_ORIGINAL = 2;
+ /**
+ * 缩放宽度至控件最大宽度,高度按比例缩放
+ */
+ int VIDEO_DISPLAY_TYPE_ZOOM = 3;
+
+ /**
+ * 已结束,或未开始
+ */
+ int MUSIC_PLAYER_STOP = 0;
+ /**
+ * 准备中
+ */
+ int MUSIC_PLAYER_PREPARE = 1;
+ /**
+ * //缓冲中
+ */
+ int MUSIC_PLAYER_BUFFER = 2;
+ /**
+ * //播放中
+ */
+ int MUSIC_PLAYER_START = 3;
+ /**
+ * //暂停
+ */
+ int MUSIC_PLAYER_PAUSE = 4;
+ /**
+ * //恢复
+ */
+ int MUSIC_PLAYER_PLAY = 5;
+ /**
+ * //跳转至某处播放中
+ */
+ int MUSIC_PLAYER_SEEK = 6;
+ /**
+ * //移动网络环境下
+ */
+ int MUSIC_PLAYER_MOBILE = 7;
+ /**
+ * //错误
+ */
+ int MUSIC_PLAYER_ERROR = 8;
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultCoverController.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultCoverController.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd64baeed3c09da548a66c7eb5e3c4b2352fd624
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultCoverController.java
@@ -0,0 +1,32 @@
+package com.example.playerharmonyos.controller;
+
+import com.example.playerharmonyos.ResourceTable;
+import com.example.playerharmonyos.base.BaseCoverController;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.Image;
+import ohos.agp.components.LayoutScatter;
+import ohos.app.Context;
+
+public class DefaultCoverController extends BaseCoverController {
+
+ /**
+ *
+ */
+ public Image imagePic;
+
+ public DefaultCoverController(Context context) {
+ this(context, null);
+ }
+
+ public DefaultCoverController(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public DefaultCoverController(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ Component component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_video_default_cover_controller_layout, null, false);
+ imagePic = (Image) component.findComponentById(ResourceTable.Id_image_pic);
+ addComponent(component);
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultGestureController.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultGestureController.java
new file mode 100644
index 0000000000000000000000000000000000000000..4fe39f20be28188d628dd78a17dfb74378eb8772
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultGestureController.java
@@ -0,0 +1,118 @@
+package com.example.playerharmonyos.controller;
+
+import com.example.playerharmonyos.ResourceTable;
+import com.example.playerharmonyos.base.BaseGestureController;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.ProgressBar;
+import ohos.agp.components.Text;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.LayoutScatter;
+import ohos.agp.components.Component;
+import ohos.app.Context;
+import ohos.multimodalinput.event.TouchEvent;
+
+public class DefaultGestureController extends BaseGestureController {
+
+ /**
+ *
+ */
+ private Context context;
+ /**
+ *
+ */
+ private DirectionalLayout dirSound;
+ /**
+ *
+ */
+ private DirectionalLayout dirPresent;
+ /**
+ *
+ */
+ private Image soundImage;
+ /**
+ *
+ */
+ private Image presentImage;
+ /**
+ *
+ */
+ private ProgressBar soundProgressBar;
+ /**
+ *
+ */
+ private ProgressBar presentProgressBar;
+ /**
+ *
+ */
+ private Text presentText;
+
+
+ public DefaultGestureController(Context context) {
+ this(context, null);
+ }
+
+ public DefaultGestureController(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+
+ }
+
+ public DefaultGestureController(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ this.context = context;
+ Component component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_default_gesture_controller_layout, null, false);
+ addComponent(component);
+
+ dirSound = (DirectionalLayout) findComponentById(ResourceTable.Id_dir_sound);
+ dirPresent = (DirectionalLayout) findComponentById(ResourceTable.Id_dir_present);
+
+
+ soundImage = (Image) findComponentById(ResourceTable.Id_sound_image);
+ presentImage = (Image) findComponentById(ResourceTable.Id_present_image);
+
+ soundProgressBar = (ProgressBar) findComponentById(ResourceTable.Id_sound_progressBar);
+ presentProgressBar = (ProgressBar) findComponentById(ResourceTable.Id_present_progressBar);
+
+ presentText = (Text) findComponentById(ResourceTable.Id_present_text);
+ }
+
+ @Override
+ public void updataGestureScene(int gestureScene) {
+
+ }
+
+ @Override
+ public void setVideoProgress(long totalTime, long speedTime, int progress) {
+
+ }
+
+ @Override
+ public void setSoundrogress(int progress) {
+
+ }
+
+ @Override
+ public void setBrightnessProgress(int progress) {
+
+ }
+
+ @Override
+ public boolean onTouchEnevt(TouchEvent e1, TouchEvent e2, float distanceX, float distanceY) {
+ return false;
+ }
+
+ @Override
+ public void onReset() {
+
+ }
+
+ @Override
+ public void onReset(long delayedMilliss) {
+
+ }
+
+ @Override
+ public void onDestroy() {
+
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultVideoController.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultVideoController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d542a64d50e3e1fd5fa3d6db20758d1e98076c67
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/controller/DefaultVideoController.java
@@ -0,0 +1,362 @@
+package com.example.playerharmonyos.controller;
+
+import com.example.playerharmonyos.ResourceTable;
+import com.example.playerharmonyos.base.BaseVideoController;
+import com.example.playerharmonyos.manager.VideoPlayerManager;
+import ohos.agp.animation.Animator;
+import ohos.agp.animation.AnimatorProperty;
+import ohos.agp.components.DirectionalLayout;
+import ohos.agp.components.Image;
+import ohos.agp.components.Slider;
+import ohos.agp.components.Text;
+import ohos.agp.components.AttrSet;
+import ohos.agp.components.Component;
+import ohos.agp.components.LayoutScatter;
+import ohos.app.Context;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+
+import java.util.Formatter;
+import java.util.Locale;
+
+public class DefaultVideoController extends BaseVideoController {
+
+ /**
+ *
+ */
+ private Context context;
+
+ /**
+ *
+ */
+ private Image imageStart;
+
+ /**
+ *
+ */
+ private Image imageLoading;
+
+ /**
+ *
+ */
+ private Image imageFullScreen;
+
+ /**
+ *
+ */
+ private Text currentTime;
+
+ /**
+ *
+ */
+ private Text totalTime;
+
+ /**
+ *
+ */
+ private Slider slider;
+
+ /**
+ *
+ */
+ private DirectionalLayout directionalLayout;
+
+ /**
+ *
+ */
+ private AnimatorProperty animatorProperty;
+
+ /**
+ *
+ */
+ private boolean touch = false;
+
+
+ /**
+ *
+ */
+ private EventRunner eventRunner = EventRunner.create();
+
+ /**
+ *
+ */
+ private EventHandler eventHandler = new EventHandler(eventRunner);
+
+ public DefaultVideoController(Context context) {
+ this(context, null);
+ }
+
+ public DefaultVideoController(Context context, AttrSet attrSet) {
+ this(context, attrSet, "");
+ }
+
+ public DefaultVideoController(Context context, AttrSet attrSet, String styleName) {
+ super(context, attrSet, styleName);
+ this.context = context;
+
+ Component component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_default_video_controller_layout, null, false);
+ addComponent(component);
+
+ directionalLayout = (DirectionalLayout) component.findComponentById(ResourceTable.Id_directionalLayout);
+ imageStart = (Image) findComponentById(ResourceTable.Id_image_start);
+ imageLoading = (Image) findComponentById(ResourceTable.Id_image_loading);
+ imageFullScreen = (Image) findComponentById(ResourceTable.Id_image_full_screen);
+ currentTime = (Text) findComponentById(ResourceTable.Id_currentTime);
+ totalTime = (Text) findComponentById(ResourceTable.Id_totalTime);
+ slider = (Slider) findComponentById(ResourceTable.Id_slider);
+
+ slider.setValueChangedListener(new Slider.ValueChangedListener() {
+ @Override
+ public void onProgressUpdated(Slider slider, int i, boolean b) {
+ if (!b) {
+ return;
+ }
+ if (!VideoPlayerManager.getInstance().isPlaying()) {
+ return;
+ }
+ long durtion = VideoPlayerManager.getInstance().getDurtion();
+ if (durtion > 0) {
+ long currentTime = i * 1000 * (durtion / 100);
+ System.out.println("currentTime====" + currentTime + "durtion====" + durtion);
+ VideoPlayerManager.getInstance().seekTo(currentTime);
+ }
+ }
+
+ @Override
+ public void onTouchStart(Slider slider) {
+ }
+
+ @Override
+ public void onTouchEnd(Slider slider) {
+ }
+ });
+ imageStart.setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ if (null != onStartListener) {
+ onStartListener.onStartPlay();
+ }
+ }
+ });
+ imageFullScreen.setClickedListener(new ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ if (null != onFuctionListener) {
+ onFuctionListener.onStartFullScreen(null);
+ }
+ }
+ });
+ }
+
+
+ /**
+ *
+ */
+ @Override
+ public void readyPlaying() {
+ directionalLayout.setVisibility(Component.VISIBLE);
+ imageStart.setVisibility(Component.HIDE);
+ imageLoading.setVisibility(Component.VISIBLE);
+ context.getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ animatorProperty = imageLoading.createAnimatorProperty();
+ animatorProperty.rotate(360)
+ .setDuration(3000).setLoopedCount(Animator.INFINITE).start();
+ }
+ });
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void startBuffer() {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void endBuffer() {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void play() {
+ if (animatorProperty != null) {
+ animatorProperty.stop();
+ animatorProperty.cancel();
+ }
+ imageLoading.setVisibility(Component.HIDE);
+
+ imageStart.setVisibility(Component.VISIBLE);
+ if (null != imageStart) {
+ imageStart.setPixelMap(ResourceTable.Media_ic_video_controller_pause);
+ }
+ changeControllerState(scrrenOrientation, false);
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void pause() {
+ if (null != imageStart) {
+ imageStart.setPixelMap(ResourceTable.Media_ic_video_controller_play);
+ }
+ if (null != imageStart) {
+ imageStart.setVisibility(Component.VISIBLE);
+ }
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void repeatPlay() {
+ if (null != imageStart) {
+ imageStart.setVisibility(Component.VISIBLE);
+ }
+ if (null != imageStart) {
+ imageStart.setPixelMap(ResourceTable.Media_ic_video_controller_pause);
+ }
+ changeControllerState(scrrenOrientation, false);
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void mobileWorkTips() {
+
+ }
+
+ @Override
+ public void error(int errorCode, String errorMessage) {
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void reset() {
+ directionalLayout.setVisibility(Component.HIDE);
+ if (null != imageStart) {
+ imageStart.setVisibility(Component.VISIBLE);
+ }
+ if (null != imageStart) {
+ imageStart.setPixelMap(ResourceTable.Media_ic_video_controller_play);
+ }
+ if (totalTime != null) {
+ totalTime.setText("00:00");
+ }
+ if (currentTime != null) {
+ currentTime.setText("00:00");
+ }
+ if (slider != null) {
+ slider.setProgressValue(0);
+ slider.setViceProgress(0);
+ }
+ }
+
+ /**
+ *
+ */
+ @Override
+ protected void onBufferingUpdate(int percent) {
+ super.onBufferingUpdate(percent);
+ }
+
+ /**
+ *
+ */
+ @Override
+ protected void onTaskRuntime(long totalDurtion, long currentDurtion, int bufferPercent) {
+ if (touch) {
+ return;
+ }
+ if (totalDurtion > 0) {
+// System.out.println("bufferPercent====" + bufferPercent);
+ if (totalTime != null) {
+ totalTime.setText(stringForAudioTime(totalDurtion));
+ currentTime.setText(stringForAudioTime(currentDurtion));
+ }
+ int progress = (int) (((float) currentDurtion / totalDurtion) * 100);
+ if (slider != null) {
+ slider.setProgressValue(progress);
+ slider.setViceProgress(bufferPercent);
+ }
+ }
+ }
+
+ /**
+ * 显示、隐藏 控制器 上下交互功能区
+ * 手动点击,根据播放状态自动处理,手势交互处理等状态
+ *
+ * @param scrrenOrientation 当前的窗口方向
+ * @param isInterceptIntent 为true:用户主动点击
+ */
+ @Override
+ protected void changeControllerState(int scrrenOrientation, boolean isInterceptIntent) {
+ //重复显示
+ if (isInterceptIntent && directionalLayout.getVisibility() == Component.VISIBLE) {
+ return;
+ }
+ eventHandler.removeTask(controllerRunnable);
+ if (directionalLayout.getVisibility() != Component.VISIBLE) {
+ directionalLayout.setVisibility(Component.VISIBLE);
+ }
+ if (imageStart.getVisibility() != Component.VISIBLE) {
+ imageStart.setVisibility(Component.VISIBLE);
+ }
+// eventHandler.postTask(controllerRunnable, 5000);
+ }
+
+ /**
+ * 负责控制器显示、隐藏
+ */
+ private Runnable controllerRunnable = new Runnable() {
+ @Override
+ public void run() {
+
+ context.getUITaskDispatcher().asyncDispatch(() -> {
+ if (null != imageStart) {
+ imageStart.setVisibility(INVISIBLE);
+ }
+ if (null != directionalLayout) {
+ directionalLayout.setVisibility(INVISIBLE);
+ }
+ });
+ }
+ };
+
+
+ /**
+ * 时长格式化
+ *
+ * @param timeMs 毫秒时间戳
+ * @return 格式化后的String时间
+ */
+ public String stringForAudioTime(long timeMs) {
+ if (timeMs <= 0 || timeMs >= 24 * 60 * 60 * 1000) {
+ return "00:00";
+ }
+ long totalSeconds = timeMs / 1000;
+ int seconds = (int) (totalSeconds % 60);
+ int minutes = (int) ((totalSeconds / 60) % 60);
+ int hours = (int) (totalSeconds / 3600);
+ StringBuilder stringBuilder = new StringBuilder();
+ Formatter mFormatter = new Formatter(stringBuilder, Locale.getDefault());
+ if (hours > 0) {
+ return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
+ } else {
+ return mFormatter.format("%02d:%02d", minutes, seconds).toString();
+ }
+ }
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/listener/PlayerEventListener.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/listener/PlayerEventListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..106ba8689183e9e14e51bc04b280151350276248
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/listener/PlayerEventListener.java
@@ -0,0 +1,55 @@
+package com.example.playerharmonyos.listener;
+
+public interface PlayerEventListener {
+
+ /**
+ * 播放器所有状态回调
+ * @param playerState 播放器内部状态,详见VideoConstants.定义
+ * @param message 1243123
+ */
+ void onVideoPlayerState(int playerState, String message);
+
+ /**
+ * 播放器准备好了 123123
+ * @param totalDurtion 总时长
+ */
+ void onPrepared(long totalDurtion);
+
+ /**
+ * 缓冲百分比 123123
+ * @param percent 百分比
+ */
+ void onBufferingUpdate(int percent);
+
+ /**
+ * 播放器反馈信息
+ * @param event 事件
+ * @param extra 123123
+ */
+ void onInfo(int event, int extra);
+
+ /**
+ * 音频地址无效,组件可处理付费购买等逻辑
+ */
+ void onVideoPathInvalid();
+
+ /**
+ * @param totalDurtion 音频总时间
+ * @param currentDurtion 当前播放的位置
+ * @param bufferPercent 缓冲进度,从常规默认切换至全屏、小窗时,应该关心此进度
+ */
+ void onTaskRuntime(long totalDurtion, long currentDurtion,int bufferPercent);
+
+ /**
+ * 播放器播放实时进度,每100毫秒回调一次
+ * @param totalPosition 视频总时长 单位毫秒
+ * @param currentPosition 播放实时位置时长,单位毫秒
+ * @param bufferPercent 缓冲进度,单位:百分比
+ */
+ void currentPosition(long totalPosition,long currentPosition,int bufferPercent);
+
+ /**
+ * 销毁
+ */
+ void onDestroy();
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/manager/VideoPlayerManager.java b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/manager/VideoPlayerManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9e5caa1826a8f9aa10a2b8cf48f19f613fdcf8b
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/java/com/example/playerharmonyos/manager/VideoPlayerManager.java
@@ -0,0 +1,380 @@
+package com.example.playerharmonyos.manager;
+
+import com.example.playerharmonyos.PlayerPresenter;
+import com.example.playerharmonyos.constant.VideoConstants;
+
+/**
+ * VideoPlayerManager 与播放器直接交互代理者
+ */
+public final class VideoPlayerManager implements PlayerPresenter {
+ /**
+ * //实例化
+ */
+ private static volatile VideoPlayerManager VIDEOPLAYERMACAGER;
+ /**
+ * //交互实现类
+ */
+ private static PlayerPresenter PLAYERPRESENTER;
+ /**
+ * //是否循环播放
+ */
+ private boolean loop;
+ /**
+ * //移动网络下是否允许播放
+ */
+ private boolean mobileWorkEnable;
+ /**
+ * //缩放类型,默认是等比缩放
+ */
+ private int videoDisplayType = VideoConstants.VIDEO_DISPLAY_TYPE_CUT;
+ /**
+ * //悬浮窗点击展开的目标Activity
+ */
+ private static String ACTIVITYCLASSNAME = null;
+ /**
+ * //是否衔接播放的
+ */
+ private boolean continuePlay;
+
+ public static VideoPlayerManager getInstance() {
+ if (null == VIDEOPLAYERMACAGER) {
+ synchronized (VideoPlayerManager.class) {
+ if (null == VIDEOPLAYERMACAGER) {
+ VIDEOPLAYERMACAGER = new VideoPlayerManager();
+ }
+ }
+ }
+ return VIDEOPLAYERMACAGER;
+ }
+
+ private VideoPlayerManager() {
+ }
+
+ /**
+ * 绑定IMediaPlayer
+ *
+ * @param iMediaPlayer 具体的实现类
+ */
+ public void setIMediaPlayer(PlayerPresenter iMediaPlayer) {
+ PLAYERPRESENTER = iMediaPlayer;
+ }
+
+ /**
+ * 设置循环模式
+ *
+ * @param loop true:循环播放 false:反之
+ * @return 自身实例
+ */
+ @Override
+ public VideoPlayerManager setLoop(boolean loop) {
+ this.loop = loop;
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.setLoop(loop);
+ }
+ return VIDEOPLAYERMACAGER;
+ }
+
+ /**
+ * 返回循环播放模式
+ *
+ * @return true:循环播放,false:不循环
+ */
+ public boolean isLoop() {
+ return loop;
+ }
+
+ /**
+ * 设置是否允许移动网络环境下工作
+ *
+ * @param enable true:允许移动网络工作 false:不允许
+ */
+ @Override
+ public void setMobileWorkEnable(boolean enable) {
+ this.mobileWorkEnable = enable;
+ }
+
+ /**
+ * 是否允许移动网络环境下工作
+ *
+ * @return 是否允许在移动网络下工作
+ */
+ public boolean isMobileWorkEnable() {
+ return mobileWorkEnable;
+ }
+
+ /**
+ * 设置视频画面显示缩放类型,如果正在播放,会立刻生效
+ *
+ * @param displayType 详见VideoConstants常量定义
+ */
+ @Override
+ public void setVideoDisplayType(int displayType) {
+ this.videoDisplayType = displayType;
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.setVideoDisplayType(displayType);
+ }
+ }
+
+ /**
+ * 返回视频画面缩放模式
+ *
+ * @return 用户设定的缩放模式
+ */
+ public int getVideoDisplayType() {
+ return videoDisplayType;
+ }
+
+ /**
+ * 指定点击通知栏后打开的Activity对象绝对路径
+ *
+ * @param className 播放器Activity绝对路径
+ */
+ public void setPlayerActivityClassName(String className) {
+ this.ACTIVITYCLASSNAME = className;
+ }
+
+ /**
+ * 返回点击通知栏后打开的Activity对象绝对路径
+ *
+ * @return 播放器Activity绝对路径
+ */
+ public String getPlayerActivityClassName() {
+ return ACTIVITYCLASSNAME;
+ }
+
+ /**
+ * 返回播放器内部播放状态
+ *
+ * @return 播放器内部播放状态
+ */
+ @Override
+ public boolean isPlaying() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.isPlaying();
+ }
+ return false;
+ }
+
+ /**
+ * 返回播放器内部工作状态
+ *
+ * @return true:正在工作,包含暂停、缓冲等 false:未工作
+ */
+ @Override
+ public boolean isWorking() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.isWorking();
+ }
+ return false;
+ }
+
+ /**
+ * 返回当前正在播放的视频宽
+ *
+ * @return 视频宽(分辨率)
+ */
+ @Override
+ public int getVideoWidth() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.getVideoWidth();
+ }
+ return 0;
+ }
+
+
+ /**
+ * 返回当前正在播放的视频高
+ *
+ * @return 视频高(分辨率)
+ */
+ @Override
+ public int getVideoHeight() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.getVideoHeight();
+ }
+ return 0;
+ }
+
+ /**
+ * 开始、暂停 播放
+ */
+ @Override
+ public void playOrPause() {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.playOrPause();
+ }
+ }
+
+ /**
+ * 恢复播放
+ */
+ @Override
+ public void play() {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.play();
+ }
+ }
+
+ /**
+ * 暂停播放
+ */
+ @Override
+ public void pause() {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.pause();
+ }
+ }
+
+ /**
+ * 释放、还原播放、监听、渲染等状态
+ */
+ @Override
+ public void onReset() {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.onReset();
+ }
+ }
+
+ /**
+ * 停止播放
+ *
+ * @param isReset 是否释放播放器
+ */
+ @Override
+ public void onStop(boolean isReset) {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.onStop(isReset);
+ }
+ }
+
+ /**
+ * 跳转至指定位置播放
+ *
+ * @param currentTime 事件位置,单位毫秒
+ */
+ @Override
+ public void seekTo(long currentTime) {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.seekTo(currentTime);
+ }
+ }
+
+ /**
+ * 返回正在播放的对象时长
+ *
+ * @return 视频总时长,单位毫秒
+ */
+ @Override
+ public long getDurtion() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.getDurtion();
+ }
+ return 0;
+ }
+
+ /**
+ * 返回已播放时长
+ *
+ * @return 已播放的视频长度,单位毫秒
+ */
+ @Override
+ public long getCurrentDurtion() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.getCurrentDurtion();
+ }
+ return 0;
+ }
+
+ /**
+ * 尝试弹射退出,若当前播放器处于迷你小窗口、全屏窗口下,则只是退出小窗口\全屏至常规窗口播放
+ * 若播放器处于常规状态下,则立即销毁播放器,销毁时内部检测了悬浮窗状态,若正在悬浮窗状态下播放,则啥也不做
+ *
+ * @return 是否可以销毁界面
+ */
+ @Override
+ public boolean isBackPressed() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.isBackPressed();
+ }
+ return true;
+ }
+
+ /**
+ * 尝试弹射退出,若当前播放器处于迷你小窗口、全屏窗口下,则只是退出小窗口\全屏至常规窗口播放
+ * 若播放器处于常规状态下,则立即销毁播放器,销毁时内部检测了悬浮窗状态,若正在悬浮窗状态下播放,则啥也不做
+ *
+ * @param destroy 是否直接销毁,比如说MainActivity返回逻辑还有询问用户是否退出,给定destroy为false,
+ * 则只是尝试弹射,并不会去销毁播放器
+ * @return 是否可以销毁界面
+ */
+ @Override
+ public boolean isBackPressed(boolean destroy) {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.isBackPressed(destroy);
+ }
+ return true;
+ }
+
+ /**
+ * 返回播放器内部播放状态
+ *
+ * @return 内部播放状态
+ */
+ @Override
+ public int getVideoPlayerState() {
+ if (null != PLAYERPRESENTER) {
+ return PLAYERPRESENTER.getVideoPlayerState();
+ }
+ return VideoConstants.MUSIC_PLAYER_STOP;
+ }
+
+
+ /**
+ * 若跳转至目标Activity后需要衔接播放,则必须设置此标记,以便在生命周期切换时处理用户动作意图
+ *
+ * @param continuePlay true:衔接播放 fasle:不衔接播放
+ */
+ @Override
+ public void setContinuePlay(boolean continuePlay) {
+ this.continuePlay = continuePlay;
+ }
+
+ /**
+ * 返回衔接播放状态
+ *
+ * @return true:衔接播放 fasle:不衔接播放
+ */
+ public boolean isContinuePlay() {
+ return continuePlay;
+ }
+
+ /**
+ * 组件处于可见状态
+ */
+ @Override
+ public void onResume() {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.onResume();
+ }
+ }
+
+ /**
+ * 组件即将处于不可见状态
+ */
+ @Override
+ public void onPause() {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.onPause();
+ }
+ }
+
+ /**
+ * 对应生命周期调用
+ */
+ @Override
+ public void onDestroy() {
+ if (null != PLAYERPRESENTER) {
+ PLAYERPRESENTER.onDestroy();
+ }
+ }
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/element/color.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..2a36b3eac50f8f1f5f1f028aa6723284a51b3b3d
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "color_000000",
+ "value": "#ffffff"
+ }
+ ]
+}
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/element/string.json b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..b42946a5d8580409fbe57973bbff712e84871ea7
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Player_harmonyos"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/graphic/background_ability_main.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/ability_main.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..daa0c3329cba008f20d86caaaeef5b204608c8ee
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/default_gesture_controller_layout.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/default_gesture_controller_layout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4e06fc5ce1cdd0f318f8d6fc43ea9fb204bc385e
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/default_gesture_controller_layout.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/default_video_controller_layout.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/default_video_controller_layout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6def65d76be05c5d0baae9167d17fa223df94c20
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/default_video_controller_layout.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/video_default_cover_controller_layout.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/video_default_cover_controller_layout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2310942bb0dceddfacad940e5d631a629ebf9676
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/video_default_cover_controller_layout.xml
@@ -0,0 +1,12 @@
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/video_default_track_layout.xml b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/video_default_track_layout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..68b5f130195ebcc9cab949b1aaadeed91c2ea5ea
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/layout/video_default_track_layout.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_brightness.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_brightness.png
new file mode 100644
index 0000000000000000000000000000000000000000..662d1e7cb7b68635d3c2bf3d3522d11b033bacbe
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_brightness.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_controller_pause.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_controller_pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c44df0371a419d8d7e06ab524cfaf5ede868860
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_controller_pause.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_controller_play.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_controller_play.png
new file mode 100644
index 0000000000000000000000000000000000000000..0254ce5ed0528b541ca75586b833c1008c6d3ebd
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_controller_play.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_cover_play.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_cover_play.png
new file mode 100644
index 0000000000000000000000000000000000000000..7bb7e4e5ee4e6c08fb92651b5de570bc6650feb6
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_cover_play.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_full_scrrent.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_full_scrrent.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee9477c1a5a1a8cbff7ca91d385a5c7303d2dd30
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_full_scrrent.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_gesture_last.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_gesture_last.png
new file mode 100644
index 0000000000000000000000000000000000000000..c71a2dc4f69603b2c928a83f644b19ca00dc795c
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_gesture_last.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_gesture_next.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_gesture_next.png
new file mode 100644
index 0000000000000000000000000000000000000000..13dcd23afdbc462877f889ddb191dd662c949ea0
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_gesture_next.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_loading_1.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_loading_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee595a594b117a1d92d294db911aa25d93b05f8c
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_loading_1.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_sound.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_sound.png
new file mode 100644
index 0000000000000000000000000000000000000000..4cf050247f501a95e646bb6bd2f4e4460d171ef3
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_sound.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_title_bar_back_noimal.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_title_bar_back_noimal.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e4b3a287d189ece9c0ebb23120c1c93c9f44a6e
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/ic_video_title_bar_back_noimal.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/icon.png b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/playerHarmonyos/src/main/resources/base/media/icon.png differ
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/settings.gradle b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..a4112d718c9dfabaaada7b8d36d013219a9fc7fb
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':playerHarmonyos'
diff --git a/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/upload.gradle b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/upload.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..8ea51d54c5fa3d6d292d583e988e0e0bfcd1f79f
--- /dev/null
+++ b/022.HarmonyPlayer_OpenHarmony-master/VideoPlayer/upload.gradle
@@ -0,0 +1,42 @@
+apply plugin: 'maven-publish'
+
+def DEFAULT_POM_NAME='seekbar_harmony'
+def DEFAULT_POM_VERSION='1.0.1' //har包版本信息
+def DEFAULT_POM_ARTIFACT_ID="harTest" //har包ID
+def DEFAULT_POM_GROUP_ID='com.example.seekbar_harmony' //项目组ID
+def DEFAULT_POM_PACKAGING='har' //包类型,固定为har
+def DEFAULT_POM_DESCRIPTION='myLib for harmonyos'
+def MAVEN_USERNAME='admin' //远程Maven仓的用户名
+def MAVEN_PASSWORD='admin' //远程Maven仓的密码
+def LOCAL_MAVEN_REPOSITORY_URL='D:/demo/' //本地Maven仓地址
+def REMOTE_MAVEN_REPOSITORY_URL='http://localhost:8888/repository/maven-releases/' //远程Maven仓地址
+
+afterEvaluate { project ->
+ DEFAULT_POM_ARTIFACT_ID = project.name
+ publishing {
+ publications {
+ maven(MavenPublication) {
+ from components.release //指定发布的har包类型为debug或release
+ group = DEFAULT_POM_GROUP_ID
+ artifactId = DEFAULT_POM_ARTIFACT_ID
+ version = DEFAULT_POM_VERSION
+ pom {
+ name = DEFAULT_POM_NAME
+ description = DEFAULT_POM_DESCRIPTION
+ packaging = DEFAULT_POM_PACKAGING
+ }
+ }
+ }
+ repositories {
+ maven {
+// url = LOCAL_MAVEN_REPOSITORY_URL //发布到本地Maven仓
+ //发布到远程Maven仓的地址以及Maven仓的帐号和密码
+ url = REMOTE_MAVEN_REPOSITORY_URL
+ credentials {
+ username MAVEN_USERNAME
+ password MAVEN_PASSWORD
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/.gitignore b/023.FileDownload_OpenHarmony-master/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/023.FileDownload_OpenHarmony-master/.idea/.gitignore b/023.FileDownload_OpenHarmony-master/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/023.FileDownload_OpenHarmony-master/.idea/compiler.xml b/023.FileDownload_OpenHarmony-master/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61a9130cd9669c3843e6445dfe1fee2d493869bc
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/.idea/gradle.xml b/023.FileDownload_OpenHarmony-master/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e8537bae67940e8b4eb379f565d2a97c206caa7b
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/gradle.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/.idea/jarRepositories.xml b/023.FileDownload_OpenHarmony-master/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7443424bc5abb3b2c16dd9751cfceb69faed
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/.idea/misc.xml b/023.FileDownload_OpenHarmony-master/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f43837a9d879322d3f3c732d212a3e507d555196
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1877049889.json b/023.FileDownload_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1877049889.json
new file mode 100644
index 0000000000000000000000000000000000000000..69beee7fd7694e767677c5d3b4863f419c2bf84e
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_1877049889.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh_CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*780"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_475387625.json b/023.FileDownload_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_475387625.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/previewer/phone/phoneSettingConfig_475387625.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/.idea/previewer/previewConfig.json b/023.FileDownload_OpenHarmony-master/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..46607e7a391bd82cd2167e8258f7215b18560280
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/.idea/previewer/previewConfig.json
@@ -0,0 +1,10 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\project\\hw\\hw\\entry": [],
+ "D:\\PCFile\\PCFile\\svn\\026.FileDownload\\updownfile\\hw\\entry": [
+ "phone"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git "a/023.FileDownload_OpenHarmony-master/023.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204updownfile\346\226\207\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" "b/023.FileDownload_OpenHarmony-master/023.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204updownfile\346\226\207\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..c9d93d72687ff1958f28acdc093e8d0c55081bf0
Binary files /dev/null and "b/023.FileDownload_OpenHarmony-master/023.\345\237\272\344\272\216\351\270\277\350\222\231\347\263\273\347\273\237\347\232\204updownfile\346\226\207\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.docx" differ
diff --git a/023.FileDownload_OpenHarmony-master/build.gradle b/023.FileDownload_OpenHarmony-master/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..0da9bc913f7350fad9087d8535f200bedce92ed3
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/build.gradle
@@ -0,0 +1,37 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.2.4.0'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/.gitignore b/023.FileDownload_OpenHarmony-master/downfile/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..603b14077394cd2294ac6922fe619669630ef3ab
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/023.FileDownload_OpenHarmony-master/downfile/.idea/gradle.xml b/023.FileDownload_OpenHarmony-master/downfile/.idea/gradle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7dc2641ad016daf55bb65711eeb91c30669e05cb
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/.idea/gradle.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/.idea/misc.xml b/023.FileDownload_OpenHarmony-master/downfile/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..707ee6e613bd5d1312003e7ef793dcbf3ff54b93
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/.idea/previewer/phone/phoneSettingConfig_475387625.json b/023.FileDownload_OpenHarmony-master/downfile/.idea/previewer/phone/phoneSettingConfig_475387625.json
new file mode 100644
index 0000000000000000000000000000000000000000..78eb57dc08fbe128df6330c0cca9865faa8e367d
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/.idea/previewer/phone/phoneSettingConfig_475387625.json
@@ -0,0 +1,25 @@
+{
+ "setting": {
+ "1.0.1": {
+ "Language": {
+ "args": {
+ "Language": "zh-CN"
+ }
+ }
+ }
+ },
+ "frontend": {
+ "1.0.0": {
+ "Resolution": {
+ "args": {
+ "Resolution": "360*750"
+ }
+ },
+ "DeviceType": {
+ "args": {
+ "DeviceType": "phone"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/.idea/previewer/previewConfig.json b/023.FileDownload_OpenHarmony-master/downfile/.idea/previewer/previewConfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..3738e7097a18aa68028e0421f33bd04ca0926b88
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/.idea/previewer/previewConfig.json
@@ -0,0 +1,7 @@
+{
+ "1.0.0": {
+ "LastPreviewDevice": {
+ "D:\\project\\hw\\hw\\entry": []
+ }
+ }
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/.idea/vcs.xml b/023.FileDownload_OpenHarmony-master/downfile/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..94a25f7f4cb416c083d265558da75d457237d671
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/build.gradle b/023.FileDownload_OpenHarmony-master/downfile/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..04b1a9f1ed7e71eae182ecfcd4425c99de2dbabd
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.0.1'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/.gitignore b/023.FileDownload_OpenHarmony-master/downfile/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/build.gradle b/023.FileDownload_OpenHarmony-master/downfile/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..b8662a9f2d267dafd0fb36da0a7783e9e32fd954
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/build.gradle
@@ -0,0 +1,16 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ implementation 'com.squareup.okhttp3:okhttp:3.4.1'
+ implementation 'io.reactivex:rxjava:1.1.6'
+ testCompile'junit:junit:4.12'
+ implementation project(path: ':updownfile')
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/config.json b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..f319d32b2f2f25a278c146454a0ba46501ddd1f7
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/config.json
@@ -0,0 +1,71 @@
+{
+ "app": {
+ "bundleName": "com.example.updownfile",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.updownfile",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.example.updownfile.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "UpDownFile",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "reqPermissions": [
+ {
+ "reason": "",
+ "name": "ohos.permission.INTERNET"
+ },
+ {
+ "reason": "",
+ "name": "ohos.permission.READ_USER_STORAGE"
+ },
+ {
+ "reason": "",
+ "name": "ohos.permission.READ_MEDIA"
+ },
+ {
+ "reason": "",
+ "name": "ohos.permission.WRITE_USER_STORAGE"
+ },
+ {
+ "reason": "",
+ "name": "ohos.permission.WRITE_MEDIA"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/MainAbility.java b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..be14e56c5ca7e1e33b8a0b2498b4f5fa95684f84
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/MainAbility.java
@@ -0,0 +1,13 @@
+package com.example.updownfile;
+
+import com.example.updownfile.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/MyApplication.java b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfb495150e98ecaa1e75575973e3b49e093b6394
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/MyApplication.java
@@ -0,0 +1,10 @@
+package com.example.updownfile;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/slice/MainAbilitySlice.java b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e71731f810b6bede77977ba08ef4313e62ffa63
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/java/com/example/updownfile/slice/MainAbilitySlice.java
@@ -0,0 +1,131 @@
+package com.example.updownfile.slice;
+
+import com.example.updownfile.ResourceTable;
+import com.example.updownfile.util.LogUtil;
+import com.example.updownfile.util.ProgressDownloader;
+import com.example.updownfile.util.ProgressResponseBody;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.ProgressBar;
+import ohos.app.Environment;
+
+import java.io.File;
+
+public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener, ProgressResponseBody.ProgressListener{
+ private ProgressBar progressBar;
+ private Button button1, button2, button3,button4,button5;
+ private long breakPoints;
+ private ProgressDownloader downloader;
+ private File file;
+ private long totalBytes;
+ private long contentLength;
+ public static final String PACKAGE_URL = "https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe";
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ intintView();//执行初始化
+ }
+
+ /**
+ * 初始化
+ */
+ private void intintView() {
+ String[] per = {"ohos.permission.READ_USER_STORAGE", "ohos.permission.WRITE_MEDIA",
+ "ohos.permission.READ_MEDIA", "ohos.permission.WRITE_USER_STORAGE"};
+ requestPermissionsFromUser(per, 0);
+ progressBar = (ProgressBar) findComponentById(ResourceTable.Id_progress);
+ button1 = (Button) findComponentById(ResourceTable.Id_button1);
+ button2 = (Button) findComponentById(ResourceTable.Id_button2);
+ button3 = (Button) findComponentById(ResourceTable.Id_button3);
+ button4
+ = (Button) findComponentById(ResourceTable.Id_button4);
+ button5 = (Button) findComponentById(ResourceTable.Id_button5);
+ button1.setClickedListener(this);
+ button2.setClickedListener(this);
+ button3.setClickedListener(this);
+ button4.setClickedListener(this);
+ button5.setClickedListener(this);
+ file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "windows.exe");
+ downloader = new ProgressDownloader(PACKAGE_URL, file, this);
+ }
+
+ @Override
+ public void onActive() {
+ super.onActive();
+ }
+
+ @Override
+ public void onForeground(Intent intent) {
+ super.onForeground(intent);
+ }
+
+ @Override
+ public void onClick(Component component) {
+ switch (component.getId()) {
+ case ResourceTable.Id_button1:
+ // 新下载前清空断点信息
+ breakPoints = 0L;
+ downloader.download(0L);
+ LogUtil.Toast(getAbility(), "开始下载");
+ break;
+ case ResourceTable.Id_button2:
+ downloader.pause();
+ // 存储此时的totalBytes,即断点位置。
+ breakPoints = totalBytes;
+ LogUtil.Toast(getAbility(), "下载暂停");
+ break;
+ case ResourceTable.Id_button3:
+ downloader.download(breakPoints);
+ LogUtil.Toast(getAbility(), "下载继续");
+ break;
+ case ResourceTable.Id_button4:
+ LogUtil.Toast(getAbility(), "开始单文件上传,等待服务器接收");
+
+ break;
+ case ResourceTable.Id_button5:
+ LogUtil.Toast(getAbility(), "开始多文件上传,等待服务器接收");
+
+ break;
+ }
+ }
+
+ @Override
+ public void onPreExecute(long contentLength) {
+ // 文件总长只需记录一次,要注意断点续传后的contentLength只是剩余部分的长度
+ if (this.contentLength == 0L) {
+ this.contentLength = contentLength;
+ getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ progressBar.setMaxValue((int) (contentLength / 1024));
+ }
+ });
+
+ }
+ }
+
+ @Override
+ public void update(long totalBytes, boolean done) {
+ // 注意加上断点的长度
+ this.totalBytes = totalBytes + breakPoints;
+ getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ progressBar.setProgressValue((int) (totalBytes + breakPoints) / 1024);
+ }
+ });
+
+ if (done) {
+ // 切换到主线程
+ getUITaskDispatcher().asyncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ LogUtil.Toast(getAbility(), "下载完成");
+ }
+ });
+ }
+ }
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/element/string.json b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..9cb9a96a71092130166c7543a2eda840631fc7db
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "UpDownFile"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/graphic/background_ability_main.xml b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/graphic/color_blue_element.xml b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/graphic/color_blue_element.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e66c5a8b0ab587a6db69e9eb8fb43373acb7cd3a
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/graphic/color_blue_element.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/layout/ability_main.xml b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1348bc65b9a58f4c211b1946398dcd5d2be63ff3
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/media/icon.png b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/023.FileDownload_OpenHarmony-master/downfile/entry/src/main/resources/base/media/icon.png differ
diff --git a/023.FileDownload_OpenHarmony-master/downfile/entry/src/test/java/com/example/updownfile/ExampleTest.java b/023.FileDownload_OpenHarmony-master/downfile/entry/src/test/java/com/example/updownfile/ExampleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5fae74f72847be39c6f693f77a7aca22266713fe
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/entry/src/test/java/com/example/updownfile/ExampleTest.java
@@ -0,0 +1,9 @@
+package com.example.updownfile;
+
+import org.junit.Test;
+
+public class ExampleTest {
+ @Test
+ public void onStart() {
+ }
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/gradle.properties b/023.FileDownload_OpenHarmony-master/downfile/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..0daf1830fbdef07e50a44d74210c8c82f1b66278
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/gradle.properties
@@ -0,0 +1,10 @@
+# Project-wide Gradle settings.
+# IDE (e.g. DevEco Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# 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.
+# If the Chinese output is garbled, please configure the following parameter.
+# org.gradle.jvmargs=-Dfile.encoding=GBK
diff --git a/023.FileDownload_OpenHarmony-master/downfile/gradle/wrapper/gradle-wrapper.jar b/023.FileDownload_OpenHarmony-master/downfile/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..490fda8577df6c95960ba7077c43220e5bb2c0d9
Binary files /dev/null and b/023.FileDownload_OpenHarmony-master/downfile/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/023.FileDownload_OpenHarmony-master/downfile/gradle/wrapper/gradle-wrapper.properties b/023.FileDownload_OpenHarmony-master/downfile/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6623300bebd011bc5f7991f4f9c389e2f67b14ac
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/023.FileDownload_OpenHarmony-master/downfile/gradlew b/023.FileDownload_OpenHarmony-master/downfile/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/023.FileDownload_OpenHarmony-master/downfile/gradlew.bat b/023.FileDownload_OpenHarmony-master/downfile/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..62bd9b9ccefea2b65ae41e5d9a545e2021b90a1d
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/023.FileDownload_OpenHarmony-master/downfile/settings.gradle b/023.FileDownload_OpenHarmony-master/downfile/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..e8e8392a2711847e4ed10ee6addbfb954271b1d5
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/settings.gradle
@@ -0,0 +1 @@
+include ':entry', ':updownfile'
diff --git a/023.FileDownload_OpenHarmony-master/downfile/updownfile/.gitignore b/023.FileDownload_OpenHarmony-master/downfile/updownfile/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/updownfile/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/023.FileDownload_OpenHarmony-master/downfile/updownfile/build.gradle b/023.FileDownload_OpenHarmony-master/downfile/updownfile/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..c340a7fcb4f66ca27e2d0cf77d8866a52ffb4afc
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/updownfile/build.gradle
@@ -0,0 +1,15 @@
+apply plugin: 'com.huawei.ohos.library'
+ohos {
+ compileSdkVersion 4
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.squareup.okhttp3:okhttp:3.4.1'
+ implementation 'io.reactivex:rxjava:1.1.6'
+ testCompile'junit:junit:4.12'
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/config.json b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..50c32a0209b33644fc8e3649287416468ae0b22d
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/config.json
@@ -0,0 +1,28 @@
+{
+ "app": {
+ "bundleName": "com.example.updownfile",
+ "vendor": "example",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 4,
+ "target": 4,
+ "releaseType": "Beta1"
+ }
+ },
+ "deviceConfig": {
+ },
+ "module": {
+ "package": "com.example.updownfile",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "updownfile",
+ "moduleType": "har"
+ }
+ }
+}
\ No newline at end of file
diff --git a/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/handler/MyEventHandler.java b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/handler/MyEventHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..04b81cacf90b3bb307e714f6b26346b4854905e3
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/handler/MyEventHandler.java
@@ -0,0 +1,66 @@
+package com.example.updownfile.handler;
+
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import ohos.eventhandler.InnerEvent;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+public class MyEventHandler extends EventHandler {
+ /**
+ * 日志
+ */
+ private static final HiLogLabel label = new HiLogLabel(3, 0xD001100, "ThreadDemo");
+
+
+ public MyEventHandler(EventRunner runner) throws IllegalArgumentException {
+ super(runner);
+ }
+
+ /**
+ * 1. 创建 EventHandler 的子类,在子类中重写实现方法 processEvent()来处理事件
+ *
+ * @param event
+ */
+ @Override
+ protected void processEvent(InnerEvent event) {
+ super.processEvent(event);
+
+ if (event == null) {
+ return;
+ }
+
+ int eventId = event.eventId;
+ long param = event.param;
+ switch ((int) (eventId | param)) {
+ case 1:
+ HiLog.info(label, "eventId | param --->" + 1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * EventHandler 投递 InnerEvent 事件
+ */
+ private void initInnerEvent() {
+ EventRunner runner = EventRunner.create(false);
+ if (runner == null) {
+ return;
+ }
+ MyEventHandler myHandler = new MyEventHandler(runner);
+ int eventId1 = 0;
+ int eventId2 = 1;
+ long param = 0;
+ Object object = null;
+ InnerEvent event1 = InnerEvent.get(eventId1, param, object);
+ InnerEvent event2 = InnerEvent.get(eventId2, param, object);
+
+ myHandler.sendEvent(event1, 0, Priority.IMMEDIATE);
+ myHandler.sendEvent(event2, 2, Priority.IMMEDIATE);
+ runner.run();
+ runner.stop();
+
+ }
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/okhttp/CallBackUtil.java b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/okhttp/CallBackUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c76fc53f8751d0e07ab0b177b1854de513dce92
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/okhttp/CallBackUtil.java
@@ -0,0 +1,216 @@
+package com.example.updownfile.okhttp;
+
+
+import com.example.updownfile.handler.MyEventHandler;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+import okhttp3.Call;
+import okhttp3.Response;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by fighting on 2021/1/18.
+ */
+public abstract class CallBackUtil {
+ public static EventRunner runner = EventRunner.create(false);
+ public static MyEventHandler myHandler = new MyEventHandler(runner);
+ public void onProgress(float progress, long total ){
+
+ };
+ public void onError(final Call call, final Exception e){
+ Runnable task1 = new Runnable() {
+ @Override
+ public void run() {
+ onFailure(call,e);
+ }
+ };
+ myHandler.postTask(task1, 0, EventHandler.Priority.IMMEDIATE);
+ runner.run();
+ runner.stop();
+ };
+ public void onSeccess(Call call, Response response){
+ final T obj = onParseResponse(call, response);
+ Runnable task2 = new Runnable() {
+ @Override
+ public void run() {
+ onResponse(obj);
+ }
+ };
+ myHandler.postTask(task2, 0, EventHandler.Priority.IMMEDIATE);
+ runner.run();
+ runner.stop();
+ };
+
+
+ /**
+ * 解析response,执行在子线程
+ */
+ public abstract T onParseResponse(Call call, Response response);
+
+ /**
+ * 访问网络失败后被调用,执行在UI线程
+ */
+ public abstract void onFailure(Call call, Exception e);
+
+ /**
+ *
+ * 访问网络成功后被调用,执行在UI线程
+ */
+ public abstract void onResponse(T response);
+
+
+ public static abstract class CallBackDefault extends CallBackUtil{
+ @Override
+ public Response onParseResponse(Call call, Response response) {
+ return response;
+ }
+ }
+
+ public static abstract class CallBackString extends CallBackUtil{
+ @Override
+ public String onParseResponse(Call call, Response response) {
+ try {
+ return response.body().string();
+ } catch (IOException e) {
+ new RuntimeException("failure");
+ return "";
+ }
+ }
+ }
+
+// public static abstract class CallBackBitmap extends CallBackUtil{
+// private int mTargetWidth;
+// private int mTargetHeight;
+//
+// public CallBackBitmap(){};
+// public CallBackBitmap(int targetWidth,int targetHeight){
+// mTargetWidth = targetWidth;
+// mTargetHeight = targetHeight;
+// };
+// public CallBackBitmap(Image imageView){
+// int width = imageView.getWidth();
+// int height = imageView.getHeight();
+// if(width <=0 || height <=0){
+// throw new RuntimeException("无法获取ImageView的width或height");
+// }
+// mTargetWidth = width;
+// mTargetHeight = height;
+// };
+// @Override
+// public PixelMap onParseResponse(Call call, Response response) {
+// if(mTargetWidth ==0 || mTargetHeight == 0){
+// return BitmapFactory.decodeStream(response.body().byteStream());
+// }else {
+// return getZoomBitmap(response);
+// }
+// }
+//
+// /**
+// * 压缩图片,避免OOM异常
+// */
+// private PixelMap getZoomBitmap(Response response) {
+// byte[] data = null;
+// try {
+// data = response.body().bytes();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// BitmapFactory.Options options = new BitmapFactory.Options();
+// options.inJustDecodeBounds = true;
+//
+// BitmapFactory.decodeByteArray(data,0,data.length,options);
+// int picWidth = options.outWidth;
+// int picHeight = options.outHeight;
+// int sampleSize = 1;
+// int heightRatio = (int) Math.floor((float) picWidth / (float) mTargetWidth);
+// int widthRatio = (int) Math.floor((float) picHeight / (float) mTargetHeight);
+// if (heightRatio > 1 || widthRatio > 1){
+// sampleSize = Math.max(heightRatio,widthRatio);
+// }
+// options.inSampleSize = sampleSize;
+// options.inJustDecodeBounds = false;
+// Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length,options);
+//
+// if(bitmap == null){
+// throw new RuntimeException("Failed to decode stream.");
+// }
+// return bitmap;
+// }
+// }
+
+ /**
+ * 下载文件时的回调类
+ */
+ public static abstract class CallBackFile extends CallBackUtil{
+
+ private final String mDestFileDir;
+ private final String mdestFileName;
+
+ /**
+ *
+ * @param destFileDir:文件目录
+ * @param destFileName:文件名
+ */
+ public CallBackFile(String destFileDir, String destFileName){
+ mDestFileDir = destFileDir;
+ mdestFileName = destFileName;
+ }
+ @Override
+ public File onParseResponse(Call call, Response response) {
+
+ InputStream is = null;
+ byte[] buf = new byte[1024];
+ int len = 0;
+ FileOutputStream fos = null;
+ try{
+ is = response.body().byteStream();
+ final long total = response.body().contentLength();
+
+ long sum = 0;
+
+ File dir = new File(mDestFileDir);
+ if (!dir.exists()){
+ dir.mkdirs();
+ }
+ File file = new File(dir, mdestFileName);
+ fos = new FileOutputStream(file);
+ while ((len = is.read(buf)) != -1){
+ sum += len;
+ fos.write(buf, 0, len);
+ final long finalSum = sum;
+ myHandler.postTask(new Runnable() {
+ @Override
+ public void run() {
+ onProgress(finalSum * 100.0f / total,total);
+ }
+ });
+
+
+ }
+ fos.flush();
+
+ return file;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally{
+ try{
+ response.body().close();
+ if (is != null) is.close();
+ } catch (IOException e){
+ }
+ try{
+ if (fos != null) fos.close();
+ } catch (IOException e){
+ }
+
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/okhttp/OkhttpUtil.java b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/okhttp/OkhttpUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..5364dfe8d5709982aeec733e6172058bdbecae74
--- /dev/null
+++ b/023.FileDownload_OpenHarmony-master/downfile/updownfile/src/main/java/com/example/updownfile/okhttp/OkhttpUtil.java
@@ -0,0 +1,304 @@
+package com.example.updownfile.okhttp;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by fighting on 2021/1/18.
+ */
+
+public class OkhttpUtil {
+
+ public static final String METHOD_GET = "GET";
+ public static final String METHOD_POST = "POST";
+ public static final String METHOD_PUT = "PUT";
+ public static final String METHOD_DELETE = "DELETE";
+
+ public static final String FILE_TYPE_FILE = "file/*";
+ public static final String FILE_TYPE_IMAGE = "image/*";
+ public static final String FILE_TYPE_AUDIO = "audio/*";
+ public static final String FILE_TYPE_VIDEO = "video/*";
+
+
+ /**
+ * get请求
+ * @param url:url
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpGet(String url, CallBackUtil callBack) {
+ okHttpGet(url, null, null, callBack);
+ }
+
+ /**
+ * get请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpGet(String url, Map paramsMap, CallBackUtil callBack) {
+ okHttpGet(url, paramsMap, null, callBack);
+ }
+
+ /**
+ * get请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param headerMap:map集合,封装请求头键值对
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpGet(String url, Map paramsMap, Map headerMap, CallBackUtil callBack) {
+ new RequestUtil(METHOD_GET, url, paramsMap, headerMap, callBack).execute();
+ }
+
+ /**
+ * post请求
+ * @param url:url
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPost(String url, CallBackUtil callBack) {
+ okHttpPost(url, null, callBack);
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPost(String url, Map paramsMap, CallBackUtil callBack) {
+ okHttpPost(url, paramsMap, null, callBack);
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param headerMap:map集合,封装请求头键值对
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPost(String url, Map paramsMap, Map headerMap, CallBackUtil callBack) {
+ new RequestUtil(METHOD_POST, url, paramsMap, headerMap, callBack).execute();
+ }
+ /**
+ * post请求
+ * @param url:url
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPut(String url, CallBackUtil callBack) {
+ okHttpPut(url, null, callBack);
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPut(String url, Map paramsMap, CallBackUtil callBack) {
+ okHttpPut(url, paramsMap, null, callBack);
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param headerMap:map集合,封装请求头键值对
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPut(String url, Map paramsMap, Map headerMap, CallBackUtil callBack) {
+ new RequestUtil(METHOD_PUT, url, paramsMap, headerMap, callBack).execute();
+ }
+ /**
+ * post请求
+ * @param url:url
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpDelete(String url, CallBackUtil callBack) {
+ okHttpDelete(url, null, callBack);
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpDelete(String url, Map paramsMap, CallBackUtil callBack) {
+ okHttpDelete(url, paramsMap, null, callBack);
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param paramsMap:map集合,封装键值对参数
+ * @param headerMap:map集合,封装请求头键值对
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpDelete(String url, Map paramsMap, Map headerMap, CallBackUtil callBack) {
+ new RequestUtil(METHOD_DELETE, url, paramsMap, headerMap, callBack).execute();
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param jsonStr:json格式的键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPostJson(String url, String jsonStr, CallBackUtil callBack) {
+ okHttpPostJson(url, jsonStr, null, callBack);
+ }
+
+ /**
+ * post请求,可以传递参数
+ * @param url:url
+ * @param jsonStr:json格式的键值对参数
+ * @param headerMap:map集合,封装请求头键值对
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpPostJson(String url, String jsonStr, Map headerMap, CallBackUtil callBack) {
+ new RequestUtil(METHOD_POST, url, jsonStr, headerMap, callBack).execute();
+ }
+
+ /**
+ * post请求,上传单个文件
+ * @param url:url
+ * @param file:File对象
+ * @param fileKey:上传参数时file对应的键
+ * @param fileType:File类型,是image,video,audio,file
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
+ */
+ public static void okHttpUploadFile(String url, File file,String fileKey, String fileType, CallBackUtil callBack) {
+ okHttpUploadFile(url, file, fileKey,fileType, null, callBack);
+ }
+
+ /**
+ * post请求,上传单个文件
+ * @param url:url
+ * @param file:File对象
+ * @param fileKey:上传参数时file对应的键
+ * @param fileType:File类型,是image,video,audio,file
+ * @param paramsMap:map集合,封装键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
+ */
+ public static void okHttpUploadFile(String url, File file, String fileKey,String fileType, Map paramsMap, CallBackUtil callBack) {
+ okHttpUploadFile(url, file,fileKey, fileType, paramsMap, null, callBack);
+ }
+
+ /**
+ * post请求,上传单个文件
+ * @param url:url
+ * @param file:File对象
+ * @param fileKey:上传参数时file对应的键
+ * @param fileType:File类型,是image,video,audio,file
+ * @param paramsMap:map集合,封装键值对参数
+ * @param headerMap:map集合,封装请求头键值对
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
+ */
+ public static void okHttpUploadFile(String url, File file, String fileKey,String fileType, Map paramsMap, Map headerMap, CallBackUtil callBack) {
+ new RequestUtil(METHOD_POST, url,paramsMap, file, fileKey,fileType, headerMap, callBack).execute();
+ }
+
+ /**
+ * post请求,上传多个文件,以list集合的形式
+ * @param url:url
+ * @param fileList:集合元素是File对象
+ * @param fileKey:上传参数时fileList对应的键
+ * @param fileType:File类型,是image,video,audio,file
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpUploadListFile(String url, List fileList, String fileKey, String fileType, CallBackUtil callBack) {
+ okHttpUploadListFile(url,null, fileList, fileKey, fileType, callBack);
+ }
+
+ /**
+ * post请求,上传多个文件,以list集合的形式
+ * @param url:url
+ * @param fileList:集合元素是File对象
+ * @param fileKey:上传参数时fileList对应的键
+ * @param fileType:File类型,是image,video,audio,file
+ * @param paramsMap:map集合,封装键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpUploadListFile(String url, Map paramsMap,List fileList, String fileKey, String fileType, CallBackUtil callBack) {
+ okHttpUploadListFile(url, paramsMap,fileList, fileKey, fileType, null, callBack);
+ }
+
+ /**
+ * post请求,上传多个文件,以list集合的形式
+ * @param url:url
+ * @param fileList:集合元素是File对象
+ * @param fileKey:上传参数时fileList对应的键
+ * @param fileType:File类型,是image,video,audio,file
+ * @param paramsMap:map集合,封装键值对参数
+ * @param headerMap:map集合,封装请求头键值对
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpUploadListFile(String url, Map paramsMap, List fileList, String fileKey, String fileType, Map headerMap, CallBackUtil callBack) {
+ new RequestUtil(METHOD_POST, url, paramsMap,fileList, fileKey, fileType, headerMap, callBack).execute();
+ }
+
+ /**
+ * post请求,上传多个文件,以map集合的形式
+ * @param url:url
+ * @param fileMap:集合key是File对象对应的键,集合value是File对象
+ * @param fileType:File类型,是image,video,audio,file
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpUploadMapFile(String url, Map fileMap, String fileType, CallBackUtil callBack) {
+ okHttpUploadMapFile(url, fileMap, fileType, null, callBack);
+ }
+
+ /**
+ * post请求,上传多个文件,以map集合的形式
+ * @param url:url
+ * @param fileMap:集合key是File对象对应的键,集合value是File对象
+ * @param fileType:File类型,是image,video,audio,file
+ * @param paramsMap:map集合,封装键值对参数
+ * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
+ */
+ public static void okHttpUploadMapFile(String url, Map fileMap, String fileType, Map | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |