Merge branch 'feature/scrollview' into 'master'
Feature/scrollview See merge request !13
This commit is contained in:
commit
3c0a270878
@ -19,6 +19,13 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity android:name=".DemoActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
123
Android/app/src/main/java/pub/doric/demo/DemoActivity.java
Normal file
123
Android/app/src/main/java/pub/doric/demo/DemoActivity.java
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* 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 pub.doric.demo;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
|
import org.greenrobot.eventbus.ThreadMode;
|
||||||
|
|
||||||
|
import pub.doric.DoricContext;
|
||||||
|
import pub.doric.DoricDriver;
|
||||||
|
import pub.doric.dev.DevPanel;
|
||||||
|
import pub.doric.dev.event.EnterDebugEvent;
|
||||||
|
import pub.doric.dev.event.QuitDebugEvent;
|
||||||
|
import pub.doric.engine.ChangeEngineCallback;
|
||||||
|
import pub.doric.utils.DoricUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: pub.doric.demo
|
||||||
|
* @Author: pengfei.zhou
|
||||||
|
* @CreateDate: 2019-11-19
|
||||||
|
*/
|
||||||
|
public class DemoActivity extends AppCompatActivity {
|
||||||
|
private DoricContext doricContext;
|
||||||
|
private DevPanel devPanel = new DevPanel();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
String source = getIntent().getStringExtra("source");
|
||||||
|
FrameLayout frameLayout = new FrameLayout(this);
|
||||||
|
addContentView(frameLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||||
|
doricContext = DoricContext.create(this, DoricUtils.readAssetFile("demo/" + source), "test");
|
||||||
|
doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
doricContext.getRootNode().setRootView(frameLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
doricContext.onShow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
doricContext.onHidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
|
||||||
|
EventBus.getDefault().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
doricContext.teardown();
|
||||||
|
EventBus.getDefault().unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
public void onEnterDebugEvent(EnterDebugEvent enterDebugEvent) {
|
||||||
|
DoricDriver.getInstance().changeJSEngine(false, new ChangeEngineCallback() {
|
||||||
|
@Override
|
||||||
|
public void changed() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
public void onQuitDebugEvent(QuitDebugEvent quitDebugEvent) {
|
||||||
|
DoricDriver.getInstance().changeJSEngine(true, new ChangeEngineCallback() {
|
||||||
|
@Override
|
||||||
|
public void changed() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
if (KeyEvent.KEYCODE_MENU == event.getKeyCode()) {
|
||||||
|
devPanel.show(getSupportFragmentManager(), "DevPanel");
|
||||||
|
}
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
}
|
@ -15,102 +15,92 @@
|
|||||||
*/
|
*/
|
||||||
package pub.doric.demo;
|
package pub.doric.demo;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.KeyEvent;
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import org.greenrobot.eventbus.EventBus;
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import pub.doric.dev.DevPanel;
|
|
||||||
import pub.doric.DoricContext;
|
|
||||||
import pub.doric.DoricDriver;
|
|
||||||
import pub.doric.dev.LocalServer;
|
|
||||||
import pub.doric.dev.event.EnterDebugEvent;
|
|
||||||
import pub.doric.dev.event.QuitDebugEvent;
|
|
||||||
import pub.doric.engine.ChangeEngineCallback;
|
|
||||||
import pub.doric.utils.DoricUtils;
|
import pub.doric.utils.DoricUtils;
|
||||||
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private DevPanel devPanel = new DevPanel();
|
|
||||||
|
|
||||||
private DoricContext doricContext;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
doricContext = DoricContext.create(this, DoricUtils.readAssetFile("demo/ListDemo.js"), "test");
|
RecyclerView recyclerView = findViewById(R.id.root);
|
||||||
doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
doricContext.getRootNode().setRootView((FrameLayout) findViewById(R.id.root));
|
|
||||||
|
|
||||||
LocalServer localServer = new LocalServer(getApplicationContext(), 8910);
|
|
||||||
try {
|
try {
|
||||||
localServer.start();
|
String[] demos = getAssets().list("demo");
|
||||||
|
List<String> ret = new ArrayList<>();
|
||||||
|
for (String str : demos) {
|
||||||
|
if (str.endsWith("js")) {
|
||||||
|
ret.add(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recyclerView.setAdapter(new MyAdapter(ret.toArray(new String[0])));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
public void onAttachedToWindow() {
|
|
||||||
super.onAttachedToWindow();
|
|
||||||
|
|
||||||
EventBus.getDefault().register(this);
|
private final String[] data;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public MyAdapter(String[] demos) {
|
||||||
protected void onDestroy() {
|
this.data = demos;
|
||||||
super.onDestroy();
|
}
|
||||||
|
|
||||||
EventBus.getDefault().unregister(this);
|
@NonNull
|
||||||
}
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
TextView textView = new TextView(parent.getContext());
|
||||||
public void onEnterDebugEvent(EnterDebugEvent enterDebugEvent) {
|
textView.setGravity(Gravity.CENTER);
|
||||||
DoricDriver.getInstance().changeJSEngine(false, new ChangeEngineCallback() {
|
textView.setLayoutParams(new ViewGroup.LayoutParams(
|
||||||
@Override
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
public void changed() {
|
DoricUtils.dp2px(50)));
|
||||||
runOnUiThread(new Runnable() {
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||||
@Override
|
return new RecyclerView.ViewHolder(textView) {
|
||||||
public void run() {
|
@Override
|
||||||
doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
public String toString() {
|
||||||
}
|
return super.toString();
|
||||||
});
|
}
|
||||||
}
|
};
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||||
public void onQuitDebugEvent(QuitDebugEvent quitDebugEvent) {
|
final TextView tv = (TextView) holder.itemView;
|
||||||
DoricDriver.getInstance().changeJSEngine(true, new ChangeEngineCallback() {
|
tv.setText(data[position]);
|
||||||
@Override
|
tv.setOnClickListener(new View.OnClickListener() {
|
||||||
public void changed() {
|
@Override
|
||||||
runOnUiThread(new Runnable() {
|
public void onClick(View v) {
|
||||||
@Override
|
Intent intent = new Intent(tv.getContext(), DemoActivity.class);
|
||||||
public void run() {
|
intent.putExtra("source", data[position]);
|
||||||
doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
tv.getContext().startActivity(intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
@Override
|
return data.length;
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
if (KeyEvent.KEYCODE_MENU == event.getKeyCode()) {
|
|
||||||
devPanel.show(getSupportFragmentManager(), "DevPanel");
|
|
||||||
}
|
}
|
||||||
return super.onKeyDown(keyCode, event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/root"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity" />
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/root"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -20,6 +20,7 @@ import android.text.TextUtils;
|
|||||||
import pub.doric.plugin.ShaderPlugin;
|
import pub.doric.plugin.ShaderPlugin;
|
||||||
import pub.doric.shader.HLayoutNode;
|
import pub.doric.shader.HLayoutNode;
|
||||||
import pub.doric.shader.ImageNode;
|
import pub.doric.shader.ImageNode;
|
||||||
|
import pub.doric.shader.ScrollerNode;
|
||||||
import pub.doric.shader.list.ListItemNode;
|
import pub.doric.shader.list.ListItemNode;
|
||||||
import pub.doric.shader.list.ListNode;
|
import pub.doric.shader.list.ListNode;
|
||||||
import pub.doric.shader.RootNode;
|
import pub.doric.shader.RootNode;
|
||||||
@ -70,6 +71,7 @@ public class DoricRegistry {
|
|||||||
this.registerViewNode(HLayoutNode.class);
|
this.registerViewNode(HLayoutNode.class);
|
||||||
this.registerViewNode(ListNode.class);
|
this.registerViewNode(ListNode.class);
|
||||||
this.registerViewNode(ListItemNode.class);
|
this.registerViewNode(ListItemNode.class);
|
||||||
|
this.registerViewNode(ScrollerNode.class);
|
||||||
initRegistry(this);
|
initRegistry(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +34,6 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
|
|||||||
private ArrayList<ViewNode> mChildNodes = new ArrayList<>();
|
private ArrayList<ViewNode> mChildNodes = new ArrayList<>();
|
||||||
private ArrayList<String> mChildViewIds = new ArrayList<>();
|
private ArrayList<String> mChildViewIds = new ArrayList<>();
|
||||||
|
|
||||||
protected boolean mReusable = false;
|
|
||||||
|
|
||||||
public GroupNode(DoricContext doricContext) {
|
public GroupNode(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
}
|
}
|
||||||
@ -80,9 +78,6 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
|
|||||||
mView.removeView(oldNode.getDoricLayer());
|
mView.removeView(oldNode.getDoricLayer());
|
||||||
ViewNode newNode = ViewNode.create(getDoricContext(), type);
|
ViewNode newNode = ViewNode.create(getDoricContext(), type);
|
||||||
newNode.setId(id);
|
newNode.setId(id);
|
||||||
if (newNode instanceof GroupNode) {
|
|
||||||
((GroupNode) newNode).mReusable = this.mReusable;
|
|
||||||
}
|
|
||||||
newNode.init(this);
|
newNode.init(this);
|
||||||
newNode.blend(model.getProperty("props").asObject());
|
newNode.blend(model.getProperty("props").asObject());
|
||||||
mChildNodes.add(idx, newNode);
|
mChildNodes.add(idx, newNode);
|
||||||
@ -126,9 +121,6 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
|
|||||||
//Insert
|
//Insert
|
||||||
ViewNode newNode = ViewNode.create(getDoricContext(), type);
|
ViewNode newNode = ViewNode.create(getDoricContext(), type);
|
||||||
newNode.setId(id);
|
newNode.setId(id);
|
||||||
if (newNode instanceof GroupNode) {
|
|
||||||
((GroupNode) newNode).mReusable = this.mReusable;
|
|
||||||
}
|
|
||||||
newNode.init(this);
|
newNode.init(this);
|
||||||
newNode.blend(model.getProperty("props").asObject());
|
newNode.blend(model.getProperty("props").asObject());
|
||||||
mChildNodes.add(newNode);
|
mChildNodes.add(newNode);
|
||||||
|
101
Android/doric/src/main/java/pub/doric/shader/ScrollerNode.java
Normal file
101
Android/doric/src/main/java/pub/doric/shader/ScrollerNode.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* 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 pub.doric.shader;
|
||||||
|
|
||||||
|
|
||||||
|
import com.github.pengfeizhou.jscore.JSObject;
|
||||||
|
import com.github.pengfeizhou.jscore.JSValue;
|
||||||
|
|
||||||
|
import pub.doric.DoricContext;
|
||||||
|
import pub.doric.extension.bridge.DoricPlugin;
|
||||||
|
import pub.doric.widget.HVScrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: pub.doric.shader
|
||||||
|
* @Author: pengfei.zhou
|
||||||
|
* @CreateDate: 2019-11-18
|
||||||
|
*/
|
||||||
|
@DoricPlugin(name = "Scroller")
|
||||||
|
public class ScrollerNode extends SuperNode<HVScrollView> {
|
||||||
|
private String mChildViewId;
|
||||||
|
private ViewNode mChildNode;
|
||||||
|
|
||||||
|
public ScrollerNode(DoricContext doricContext) {
|
||||||
|
super(doricContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViewNode getSubNodeById(String id) {
|
||||||
|
return id.equals(mChildNode.getId()) ? mChildNode : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void blendSubNode(JSObject subProperties) {
|
||||||
|
if (mChildNode != null) {
|
||||||
|
mChildNode.blend(subProperties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HVScrollView build() {
|
||||||
|
return new HVScrollView(getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void blend(HVScrollView view, String name, JSValue prop) {
|
||||||
|
if ("content".equals(name)) {
|
||||||
|
mChildViewId = prop.asString().value();
|
||||||
|
} else {
|
||||||
|
super.blend(view, name, prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blend(JSObject jsObject) {
|
||||||
|
super.blend(jsObject);
|
||||||
|
JSObject contentModel = getSubModel(mChildViewId);
|
||||||
|
if (contentModel == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String viewId = contentModel.getProperty("id").asString().value();
|
||||||
|
String type = contentModel.getProperty("type").asString().value();
|
||||||
|
JSObject props = contentModel.getProperty("props").asObject();
|
||||||
|
if (mChildNode != null) {
|
||||||
|
if (mChildNode.getId().equals(viewId)) {
|
||||||
|
//skip
|
||||||
|
} else {
|
||||||
|
if (mReusable && type.equals(mChildNode.getType())) {
|
||||||
|
mChildNode.setId(viewId);
|
||||||
|
mChildNode.blend(props);
|
||||||
|
} else {
|
||||||
|
mView.removeAllViews();
|
||||||
|
mChildNode = ViewNode.create(getDoricContext(), type);
|
||||||
|
mChildNode.setId(viewId);
|
||||||
|
mChildNode.init(this);
|
||||||
|
mChildNode.blend(props);
|
||||||
|
mView.addView(mChildNode.getDoricLayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mChildNode = ViewNode.create(getDoricContext(), type);
|
||||||
|
mChildNode.setId(viewId);
|
||||||
|
mChildNode.init(this);
|
||||||
|
mChildNode.blend(props);
|
||||||
|
mView.addView(mChildNode.getDoricLayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -35,6 +35,7 @@ import pub.doric.utils.DoricUtils;
|
|||||||
*/
|
*/
|
||||||
public abstract class SuperNode<V extends View> extends ViewNode<V> {
|
public abstract class SuperNode<V extends View> extends ViewNode<V> {
|
||||||
private Map<String, JSObject> subNodes = new HashMap<>();
|
private Map<String, JSObject> subNodes = new HashMap<>();
|
||||||
|
protected boolean mReusable = false;
|
||||||
|
|
||||||
public SuperNode(DoricContext doricContext) {
|
public SuperNode(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
|
@ -37,7 +37,9 @@ public class TextNode extends ViewNode<TextView> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TextView build() {
|
protected TextView build() {
|
||||||
return new TextView(getContext());
|
TextView tv = new TextView(getContext());
|
||||||
|
tv.setGravity(Gravity.CENTER);
|
||||||
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,6 +55,9 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
|
|||||||
private DoricLayer doricLayer;
|
private DoricLayer doricLayer;
|
||||||
|
|
||||||
public void init(SuperNode superNode) {
|
public void init(SuperNode superNode) {
|
||||||
|
if (this instanceof SuperNode) {
|
||||||
|
((SuperNode<T>) this).mReusable = superNode.mReusable;
|
||||||
|
}
|
||||||
this.mSuperNode = superNode;
|
this.mSuperNode = superNode;
|
||||||
this.mLayoutParams = superNode.generateDefaultLayoutParams();
|
this.mLayoutParams = superNode.generateDefaultLayoutParams();
|
||||||
this.doricLayer = new DoricLayer(getContext());
|
this.doricLayer = new DoricLayer(getContext());
|
||||||
|
2284
Android/doric/src/main/java/pub/doric/widget/HVScrollView.java
Normal file
2284
Android/doric/src/main/java/pub/doric/widget/HVScrollView.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,4 +2,5 @@ export default [
|
|||||||
'src/Counter',
|
'src/Counter',
|
||||||
'src/Snake',
|
'src/Snake',
|
||||||
'src/ListDemo',
|
'src/ListDemo',
|
||||||
|
'src/ScrollerDemo',
|
||||||
]
|
]
|
59
demo/src/ScrollerDemo.ts
Normal file
59
demo/src/ScrollerDemo.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, scroller } from "doric";
|
||||||
|
const colors = [
|
||||||
|
"#f0932b",
|
||||||
|
"#eb4d4b",
|
||||||
|
"#6ab04c",
|
||||||
|
"#e056fd",
|
||||||
|
"#686de0",
|
||||||
|
"#30336b",
|
||||||
|
]
|
||||||
|
@Entry
|
||||||
|
class ScrollerPanel extends Panel {
|
||||||
|
build(rootView: Group): void {
|
||||||
|
rootView.addChild(scroller(vlayout(
|
||||||
|
[
|
||||||
|
// ...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5].map(e => text({
|
||||||
|
// text: colors[e % colors.length],
|
||||||
|
// textColor: Color.parse('#ffffff'),
|
||||||
|
// textSize: 20,
|
||||||
|
// bgColor: Color.parse(colors[e % colors.length]),
|
||||||
|
// layoutConfig: {
|
||||||
|
// widthSpec: LayoutSpec.EXACTLY,
|
||||||
|
// heightSpec: LayoutSpec.EXACTLY,
|
||||||
|
// },
|
||||||
|
// width: 200,
|
||||||
|
// height: 50,
|
||||||
|
// })),
|
||||||
|
...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5].map(i => hlayout([
|
||||||
|
...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5].map(j => text({
|
||||||
|
text: colors[(i + j) % colors.length],
|
||||||
|
textColor: Color.parse('#ffffff'),
|
||||||
|
textSize: 20,
|
||||||
|
bgColor: Color.parse(colors[(i + j) % colors.length]),
|
||||||
|
layoutConfig: {
|
||||||
|
widthSpec: LayoutSpec.EXACTLY,
|
||||||
|
heightSpec: LayoutSpec.EXACTLY,
|
||||||
|
},
|
||||||
|
width: 80,
|
||||||
|
height: 50,
|
||||||
|
})),
|
||||||
|
]).also(it => it.space = 20)),
|
||||||
|
hlayout([
|
||||||
|
...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5].map(e => text({
|
||||||
|
text: colors[e % colors.length],
|
||||||
|
textColor: Color.parse('#ffffff'),
|
||||||
|
textSize: 20,
|
||||||
|
bgColor: Color.parse(colors[e % colors.length]),
|
||||||
|
layoutConfig: {
|
||||||
|
widthSpec: LayoutSpec.EXACTLY,
|
||||||
|
heightSpec: LayoutSpec.EXACTLY,
|
||||||
|
},
|
||||||
|
width: 200,
|
||||||
|
height: 50,
|
||||||
|
})),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
).also(it => it.space = 20)))
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@
|
|||||||
E2334B0822E9D2070098A085 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B0722E9D2070098A085 /* ExampleTests.m */; };
|
E2334B0822E9D2070098A085 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B0722E9D2070098A085 /* ExampleTests.m */; };
|
||||||
E2334B1322E9D2070098A085 /* ExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B1222E9D2070098A085 /* ExampleUITests.m */; };
|
E2334B1322E9D2070098A085 /* ExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B1222E9D2070098A085 /* ExampleUITests.m */; };
|
||||||
E2BF7BF7237E8E9F001B0EDC /* ListDemo.js in Resources */ = {isa = PBXBuildFile; fileRef = E2BF7BF6237E8E9F001B0EDC /* ListDemo.js */; };
|
E2BF7BF7237E8E9F001B0EDC /* ListDemo.js in Resources */ = {isa = PBXBuildFile; fileRef = E2BF7BF6237E8E9F001B0EDC /* ListDemo.js */; };
|
||||||
|
E2F447F42383924B00073C7F /* ScrollerDemo.js in Resources */ = {isa = PBXBuildFile; fileRef = E2F447F32383924B00073C7F /* ScrollerDemo.js */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -69,6 +70,7 @@
|
|||||||
E2334B1222E9D2070098A085 /* ExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleUITests.m; sourceTree = "<group>"; };
|
E2334B1222E9D2070098A085 /* ExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleUITests.m; sourceTree = "<group>"; };
|
||||||
E2334B1422E9D2070098A085 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
E2334B1422E9D2070098A085 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
E2BF7BF6237E8E9F001B0EDC /* ListDemo.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = ListDemo.js; sourceTree = "<group>"; };
|
E2BF7BF6237E8E9F001B0EDC /* ListDemo.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = ListDemo.js; sourceTree = "<group>"; };
|
||||||
|
E2F447F32383924B00073C7F /* ScrollerDemo.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = ScrollerDemo.js; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -125,6 +127,7 @@
|
|||||||
E21DC9D12302865E00660C5C /* src */ = {
|
E21DC9D12302865E00660C5C /* src */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E2F447F32383924B00073C7F /* ScrollerDemo.js */,
|
||||||
E2BF7BF6237E8E9F001B0EDC /* ListDemo.js */,
|
E2BF7BF6237E8E9F001B0EDC /* ListDemo.js */,
|
||||||
E21DC9D22302865E00660C5C /* Snake.js */,
|
E21DC9D22302865E00660C5C /* Snake.js */,
|
||||||
E21DC9D32302865E00660C5C /* Counter.js */,
|
E21DC9D32302865E00660C5C /* Counter.js */,
|
||||||
@ -298,6 +301,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
E2F447F42383924B00073C7F /* ScrollerDemo.js in Resources */,
|
||||||
E2BF7BF7237E8E9F001B0EDC /* ListDemo.js in Resources */,
|
E2BF7BF7237E8E9F001B0EDC /* ListDemo.js in Resources */,
|
||||||
E21DC9D42302870000660C5C /* Snake.js in Resources */,
|
E21DC9D42302870000660C5C /* Snake.js in Resources */,
|
||||||
E21DC9D52302870000660C5C /* Counter.js in Resources */,
|
E21DC9D52302870000660C5C /* Counter.js in Resources */,
|
||||||
|
@ -26,7 +26,7 @@ @implementation ViewController
|
|||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"ListDemo" ofType:@"js"];
|
NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"ScrollerDemo" ofType:@"js"];
|
||||||
NSString *jsContent = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
|
NSString *jsContent = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
|
||||||
self.doricContext = [[DoricContext alloc] initWithScript:jsContent source:@"test.js"];
|
self.doricContext = [[DoricContext alloc] initWithScript:jsContent source:@"test.js"];
|
||||||
[self.doricContext.rootNode setupRootView:[[DoricStackView new] also:^(DoricStackView *it) {
|
[self.doricContext.rootNode setupRootView:[[DoricStackView new] also:^(DoricStackView *it) {
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#import "DoricImageNode.h"
|
#import "DoricImageNode.h"
|
||||||
#import "DoricListNode.h"
|
#import "DoricListNode.h"
|
||||||
#import "DoricListItemNode.h"
|
#import "DoricListItemNode.h"
|
||||||
|
#import "DoricScrollerNode.h"
|
||||||
|
|
||||||
@interface DoricRegistry ()
|
@interface DoricRegistry ()
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ - (void)innerRegister {
|
|||||||
[self registerViewNode:DoricImageNode.class withName:@"Image"];
|
[self registerViewNode:DoricImageNode.class withName:@"Image"];
|
||||||
[self registerViewNode:DoricListNode.class withName:@"List"];
|
[self registerViewNode:DoricListNode.class withName:@"List"];
|
||||||
[self registerViewNode:DoricListItemNode.class withName:@"ListItem"];
|
[self registerViewNode:DoricListItemNode.class withName:@"ListItem"];
|
||||||
|
[self registerViewNode:DoricScrollerNode.class withName:@"Scroller"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)registerJSBundle:(NSString *)bundle withName:(NSString *)name {
|
- (void)registerJSBundle:(NSString *)bundle withName:(NSString *)name {
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface DoricGroupNode <V:UIView *> : DoricSuperNode<V>
|
@interface DoricGroupNode <V:UIView *> : DoricSuperNode<V>
|
||||||
@property(nonatomic, assign) BOOL reusable;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -34,7 +34,6 @@ - (instancetype)initWithContext:(DoricContext *)doricContext {
|
|||||||
if (self = [super initWithContext:doricContext]) {
|
if (self = [super initWithContext:doricContext]) {
|
||||||
_childNodes = @[];
|
_childNodes = @[];
|
||||||
_childViewIds = @[];
|
_childViewIds = @[];
|
||||||
_reusable = NO;
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,11 @@ - (instancetype)initWithContext:(DoricContext *)doricContext {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
||||||
|
[super initWithSuperNode:superNode];
|
||||||
|
self.reusable = YES;
|
||||||
|
}
|
||||||
|
|
||||||
- (DoricStackView *)build {
|
- (DoricStackView *)build {
|
||||||
return [DoricListItemView new];
|
return [DoricListItemView new];
|
||||||
}
|
}
|
||||||
|
9
iOS/Pod/Classes/Shader/DoricScrollerNode.h
Normal file
9
iOS/Pod/Classes/Shader/DoricScrollerNode.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Created by pengfei.zhou on 2019/11/19.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "DoricSuperNode.h"
|
||||||
|
|
||||||
|
@interface DoricScrollerNode : DoricSuperNode<UIScrollView *>
|
||||||
|
@end
|
90
iOS/Pod/Classes/Shader/DoricScrollerNode.m
Normal file
90
iOS/Pod/Classes/Shader/DoricScrollerNode.m
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// Created by pengfei.zhou on 2019/11/19.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "DoricScrollerNode.h"
|
||||||
|
#import "DoricExtensions.h"
|
||||||
|
|
||||||
|
@interface DoricScrollView : UIScrollView
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation DoricScrollView
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
if (self.subviews.count > 0) {
|
||||||
|
UIView *child = self.subviews[0];
|
||||||
|
[self setContentSize:child.frame.size];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGSize)sizeThatFits:(CGSize)size {
|
||||||
|
if (self.subviews.count > 0) {
|
||||||
|
UIView *child = self.subviews[0];
|
||||||
|
CGSize childSize = [child sizeThatFits:size];
|
||||||
|
return CGSizeMake(MIN(size.width, childSize.width), MIN(size.height, childSize.height));
|
||||||
|
}
|
||||||
|
return CGSizeZero;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface DoricScrollerNode ()
|
||||||
|
@property(nonatomic, strong) DoricViewNode *childNode;
|
||||||
|
@property(nonatomic, copy) NSString *childViewId;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation DoricScrollerNode
|
||||||
|
- (UIScrollView *)build {
|
||||||
|
return [DoricScrollView new];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)blend:(NSDictionary *)props {
|
||||||
|
[super blend:props];
|
||||||
|
NSDictionary *childModel = [self subModelOf:self.childViewId];
|
||||||
|
if (!childModel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NSString *viewId = childModel[@"id"];
|
||||||
|
NSString *type = childModel[@"type"];
|
||||||
|
NSDictionary *childProps = childModel[@"props"];
|
||||||
|
if (self.childNode) {
|
||||||
|
if ([self.childNode.viewId isEqualToString:viewId]) {
|
||||||
|
//skip
|
||||||
|
} else {
|
||||||
|
if (self.reusable && [type isEqualToString:self.childNode.type]) {
|
||||||
|
[self.childNode also:^(DoricViewNode *it) {
|
||||||
|
it.viewId = viewId;
|
||||||
|
[it blend:childProps];
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[self.childNode.view removeFromSuperview];
|
||||||
|
self.childNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) {
|
||||||
|
it.viewId = viewId;
|
||||||
|
[it initWithSuperNode:self];
|
||||||
|
[it blend:childProps];
|
||||||
|
[self.view addSubview:it.view];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.childNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) {
|
||||||
|
it.viewId = viewId;
|
||||||
|
[it initWithSuperNode:self];
|
||||||
|
[it blend:childProps];
|
||||||
|
[self.view addSubview:it.view];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)blendView:(UIScrollView *)view forPropName:(NSString *)name propValue:(id)prop {
|
||||||
|
if ([@"content" isEqualToString:name]) {
|
||||||
|
self.childViewId = prop;
|
||||||
|
} else {
|
||||||
|
[super blendView:view forPropName:name propValue:prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)blendSubNode:(NSDictionary *)subModel {
|
||||||
|
[self.childNode blend:subModel];
|
||||||
|
}
|
||||||
|
@end
|
@ -21,6 +21,8 @@
|
|||||||
#import "DoricViewNode.h"
|
#import "DoricViewNode.h"
|
||||||
|
|
||||||
@interface DoricSuperNode<V:UIView *> : DoricViewNode<V>
|
@interface DoricSuperNode<V:UIView *> : DoricViewNode<V>
|
||||||
|
@property(nonatomic, assign) BOOL reusable;
|
||||||
|
|
||||||
- (DoricLayoutConfig *)generateDefaultLayoutParams;
|
- (DoricLayoutConfig *)generateDefaultLayoutParams;
|
||||||
|
|
||||||
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutConfig;
|
- (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layoutConfig;
|
||||||
|
@ -81,6 +81,9 @@ - (instancetype)initWithContext:(DoricContext *)doricContext {
|
|||||||
|
|
||||||
|
|
||||||
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
- (void)initWithSuperNode:(DoricSuperNode *)superNode {
|
||||||
|
if ([self isKindOfClass:[DoricSuperNode class]]) {
|
||||||
|
((DoricSuperNode *) self).reusable = superNode.reusable;
|
||||||
|
}
|
||||||
self.superNode = superNode;
|
self.superNode = superNode;
|
||||||
self.view = [[self build] also:^(UIView *it) {
|
self.view = [[self build] also:^(UIView *it) {
|
||||||
it.layoutConfig = [superNode generateDefaultLayoutParams];
|
it.layoutConfig = [superNode generateDefaultLayoutParams];
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
export * from "./src/ui/view"
|
export * from "./src/ui/view"
|
||||||
export * from "./src/ui/layout"
|
export * from "./src/ui/layout"
|
||||||
export * from "./src/ui/listview"
|
export * from "./src/ui/listview"
|
||||||
|
export * from "./src/ui/scroller"
|
||||||
export * from "./src/ui/widgets"
|
export * from "./src/ui/widgets"
|
||||||
export * from "./src/ui/panel"
|
export * from "./src/ui/panel"
|
||||||
export * from "./src/ui/declarative"
|
export * from "./src/ui/declarative"
|
||||||
|
@ -193,6 +193,18 @@ export function jsObtainContext(id: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function jsReleaseContext(id: string) {
|
export function jsReleaseContext(id: string) {
|
||||||
|
const context = gContexts.get(id)
|
||||||
|
if (context) {
|
||||||
|
timerInfos.forEach((v, k) => {
|
||||||
|
if (v.context === context) {
|
||||||
|
if (global.nativeClearTimer === undefined) {
|
||||||
|
return Reflect.apply(_clearTimeout, undefined, arguments)
|
||||||
|
}
|
||||||
|
timerInfos.delete(k)
|
||||||
|
nativeClearTimer(k)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
gContexts.delete(id)
|
gContexts.delete(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
js-framework/src/ui/scroller.ts
Normal file
43
js-framework/src/ui/scroller.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
import { Superview, View, Property, IView, LayoutSpec } from './view'
|
||||||
|
|
||||||
|
export function scroller(content: View) {
|
||||||
|
return (new Scroller).also(v => {
|
||||||
|
v.layoutConfig = {
|
||||||
|
widthSpec: LayoutSpec.WRAP_CONTENT,
|
||||||
|
heightSpec: LayoutSpec.WRAP_CONTENT,
|
||||||
|
}
|
||||||
|
v.content = content
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IScroller extends IView {
|
||||||
|
content: View
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Scroller extends Superview implements IScroller {
|
||||||
|
content!: View
|
||||||
|
|
||||||
|
allSubviews() {
|
||||||
|
return [this.content]
|
||||||
|
}
|
||||||
|
|
||||||
|
toModel() {
|
||||||
|
this.dirtyProps.content = this.content.viewId
|
||||||
|
return super.toModel()
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user