flex mobile - performance of spark List with ItemRenderers that has large image - list

I'm developing the spark List with Large Images in flex mobile.
Each ItemRenderer has a large image.
like this.
<s:ItemRenderer>
...
<s:BitmapImage source="{data.bmpData}" />
</s:ItemRenderer>
In dataProvider, there is BitmapData as name "bmpData".
The problem is performance while scrolling.
While scrolling, it stopped for a while when new Image is rendered.
help me please.

If the problem is you render too many bitmapdata in same time, you can render them one by one in different frames.
Here is an example.
Make a custom ItemRenderer
class YourItemRenderer
{
override public function set data(value:Object):void
{
if (super.data != value)
{
super.data = value;
yourBitmapImage.source = null;
//when the data change, don't call the render function directly
EnterFrameManager.getInstance().addRenderFunction(render)
}
}
private function render():void
{
if (yourBitmapImage != null && data != null)
{
yourBitmapImage.source = data.bmpData;
}
}
}
EnterFrameManager is used to control the render functions.
class EnterFrameManager
{
import mx.core.FlexGlobals;
public function EnterFrameManager()
{
FlexGlobals.topLevelApplication.addEventListener( Event.EnterFrame, onEnterFrameHandler)
}
private var _instance:EnterFrameManager;
public static function getInstance():EnterFrameManager
{
if (_instance == null)
{
_instance = new EnterFrameManager();
}
return instance;
}
//save the render functions
private var renderQueue:Array = [];
private var nowIntervalFrame:int = 0;
//change it to small value when you don't feel lag
private const UPDATE_INTERVAL_FRAMES:int = 6;
private function onEnterFrameHandler(e:Event):void
{
nowIntervalFrame++;
if (nowIntervalFrame >= UPDATE_INTERVAL_FRAMES)
{
nowIntervalFrame = 0;
//change renderQueue by waitQueue
for each (var f:Function in waitQueue)
{
addFunctionToQueue(f, renderQueue);
}
waitQueue.length = 0;
if (renderQueue.length > 0)
{
var f:Function = renderQueue.shift();
f();
}
}
}
private var waitQueue:Array = [];
public function addRenderFunction(f:Function):void
{
addFunctionToQueue(f, waitQueue);
}
private function addFunctionToQueue(f:Function, queue:Function):void
{
var index:int = queue.indexOf(f);
if (index == -1)
{
queue.push(f);
}
else
{
var temp:Function = queue.splice(index, 1);
queue.push(temp);
}
}
}

Related

Take pictures from fragmento Android

I'm trying to take a picture from a Fragment but Activityresultlauncher won't fire, it works in Activity but I'm using Viewpager/Tablayout.
When I debugged only fire when I cancel the camera.
Please someone can Help me.
Here's my code.
public class FragmentUsuario extends Fragment {
FragmentUsuarioBinding dtb;
ActivityResultLauncher<Intent> launcherVoltAct = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
int rotation = MisFunciones.getImageOrientation(mFotoFile.getAbsolutePath());
File newImage = MisFunciones.reSaveBitmap(MisFunciones.ruta_fotos + File.separator, MisFunciones.getCode() + ".JPG", rotation, mFotoFile);
}
});
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
dtb = FragmentUsuarioBinding.inflate(inflater, container, false);
return dtb.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
dtb.fotoVoltAct.setOnClickListener(v -> takeFoto());
}
private void takeFoto() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.setPackage("net.sourceforge.opencamera");
if (cameraIntent.resolveActivity(requireActivity().getPackageManager()) != null) {
mFotoFile = MisFunciones.crearImageFile();
Uri uri = FileProvider.getUriForFile(requireContext(), requireActivity().getPackageName() + ".provider", mFotoFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
launcherVoltAct.launch(cameraIntent);
}
}
}

asynchronous initialisation with swiftui

Basically - I run up against this a lot - I don't understand how you correctly do asynchronous initialisation in swift with callbacks. (with combine - I can do it). In particular - I have this code:
struct MyView : View {
#State var initialised : Bool = false
init()
{
var initialisedBinding = $initialised
Photos.PHPhotoLibrary.RequestAuthorization {
status in
if (status == Photos.PHAuthorizationStatus.authorized) {
print("here I am")
initialisedBinding.wrappedValue = true
initialisedBinding.update()
}
}
}
var body : some View {
VStack {
if (initialised) {
Text("yep")
} else {
Text("nope")
}
}
}
And when I run it - I get the print out - but the text never changes - it always remains "nope". What am I doing wrong, and how do I do it right? (Without using combine - I can do it with like a currentValueSubject and a .onreceive - but it's extra overhead, and I really want to know why the above code doesn't work - obviously I'm understanding something bad)
State is not ready in init yet, so you bound to nowhere. Moreover such activity in init is not good, because view can be created many times during rendering. The more appropriate place is .onAppear
struct MyView : View {
#State var initialised : Bool = false
var body : some View {
VStack {
if (initialised) {
Text("yep")
} else {
Text("nope")
}
}.onAppear {
Photos.PHPhotoLibrary.RequestAuthorization {
status in
if (status == Photos.PHAuthorizationStatus.authorized) {
print("here I am")
self.initialised = true
}
}
}
}
}

Custom Checkbox Category Selector

I want to filter my Data Array by different categories. It is working, but it should pick the rows of multiple categories. if multiple checkboxes are checked. How can I implement this code?
Here is my code:
check_cells = function() {
var values = [];
if (document.getElementById("checkbox_pouch").checked == true) {
values.push('pouch');
}
if (document.getElementById("checkbox_18650").checked == true) {
values.push('18650');
}
if (document.getElementById("checkbox_21700").checked == true) {
values.push('21700');
}
if (document.getElementById("checkbox_pouch").checked == false && document.getElementById("checkbox_18650").checked == false && document.getElementById("checkbox_21700").checked == false) {
values.push('empty');
}
if (values.length > 0) {
view.setRows(data.getFilteredRows([{
column:2,
test: function (value) {
return (values.indexOf(value) > -1);
}
}]));
}
dashboard.draw(view, drawOptions);
}
else {
view.setRows(data.getFilteredRows([{column:2}]));
dashboard.draw(view);
}
}
var view = new google.visualization.DataView(data);
var drawOptions = {
showRowNumber: false,
allowHtml: true,
};
// Inititial Draw of the dashboard.
dashboard.draw(view, drawOptions);
when filtering on multiple values,
you will need to combine those into one filter setting.
the data view will not let you have multiple filters on the same column.
in this case, you can use the test callback function, rather than the value key.
here, an array is used to gather the values,
and the test callback to filter the column...
check_pouch = function() {
var values = [];
if (document.getElementById("checkbox_pouch").checked == true) {
values.push('pouch');
}
if (document.getElementById("checkbox_18650").checked == true) {
values.push('18650');
}
if (values.length > 0) {
view.setRows(data.getFilteredRows([{
column:2,
test: function (value) {
return (values.indexOf(value) > -1);
}
}]));
}
dashboard.draw(view);
}

numeric soft keyboard in android using ndk

I have a java code that displays the numeric soft keyboard in Android:
public class MainActivity extends Activity {
EditText ed1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ed1 = (EditText) findViewById(R.id.editText1);
ed1.setInputType(InputType.TYPE_CLASS_NUMBER);
}
}
My activity_main.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="numberkeypad.inputmethod.MainActivity" >
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:ems="10" >
</EditText>
The output is: numeric soft keyboard
I want to display the same keyboard using NDK JNI call and no EditText. I have implemented the default keyboard in this way using the following link:
How to show the soft keyboard on native activity
But I am facing a lot of trouble using the same methodology for the numeric keyboard. Any help would be great..Thanks!
Could not find a way to do this directly, had to override the onCreateInputConnection method of View class, and then make a JNI call to a function using the overridden method.
public class NumbersView extends View {
public NumbersView(Context context) {
super(context);
}
#Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
switch(SystemKeyboardType){
case InputType.TYPE_CLASS_PHONE:
outAttrs.inputType |= InputType.TYPE_CLASS_PHONE;
break;
case InputType.TYPE_CLASS_TEXT:
outAttrs.inputType |= InputType.TYPE_CLASS_TEXT;
break;
case InputType.TYPE_CLASS_NUMBER:
outAttrs.inputType |= InputType.TYPE_CLASS_NUMBER;
break;
case InputType.TYPE_CLASS_DATETIME:
outAttrs.inputType |= InputType.TYPE_CLASS_DATETIME;
break;
default:
outAttrs.inputType |= InputType.TYPE_CLASS_TEXT;
break;
}
return inputConnection;
}
}
**/
#Override
protected void onCreate(Bundle savedInstanceState) {
calculateDeviceDPI();
super.onCreate(savedInstanceState);
myView = new NumbersView(getApplicationContext());
addContentView(myView,new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
myView.setFocusable(true);
myView.setFocusableInTouchMode(true);
//myView.requestFocus();
mContext = this;
}
public void displaySystemKeyboard(String keyboardType){
if(keyboardType.equals("text")) {
SystemKeyboardType = InputType.TYPE_CLASS_TEXT;
}
else if(keyboardType.equals("phone")) {
SystemKeyboardType = InputType.TYPE_CLASS_PHONE;
}
else if(keyboardType.equals("number")) {
SystemKeyboardType = InputType.TYPE_CLASS_NUMBER;
}
else if(keyboardType.equals("datetime")) {
SystemKeyboardType = InputType.TYPE_CLASS_DATETIME;
}
else {
SystemKeyboardType = InputType.TYPE_CLASS_DATETIME;
}
Context ctx = getApplicationContext();
InputMethodManager mgr = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
myView.requestFocus();
// only will trigger it if no physical keyboard is open
mgr.restartInput(myView);
mgr.showSoftInput(myView, 0);
}
public void hideSystemKeyboard(){
Context ctx = getApplicationContext();
View myView = this.getWindow().getDecorView();
InputMethodManager mgr = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(myView.getWindowToken(), 0);
}
And finally made a JNI call to the function:
if(pShow){
jmethodID showSysKeys = lJNIEnv->GetMethodID(lClassDeviceAPI,"displaySystemKeyboard","(Ljava/lang/String;)V");
if(showSysKeys == NULL){
LOGI("displaySystemKeyboard::Couldn't get void displaySystemKeyboard Method");
return;
}
jstring keyboardType = lJNIEnv->NewStringUTF(KeyboardType.c_str());
if(!keyboardType)
{
LOGI( "failed to alloc param string in java." );
return;
};
lJNIEnv->CallVoidMethod(lObjDeviceAPI,showSysKeys, keyboardType);
}
else{
jmethodID hideSysKeys = lJNIEnv->GetMethodID(lClassDeviceAPI,"hideSystemKeyboard","()V");
if(hideSysKeys == NULL){
LOGI("hideSystemKeyboard::Couldn't get void hideSystemKeyboard Method");
return;
}
lJNIEnv->CallVoidMethod(lObjDeviceAPI,hideSysKeys);
}
lJavaVM->DetachCurrentThread();

how to refresh the linear layout view after deleting an element

I have a simple app, in one activity I take name and date of birth. I store it in the database. and in the main activity I have linearlayout which will show all the names.
When I click on any of the name in the main activity, it should delete that name from the database and also refresh the view.
I am able to delete the entry from database, but my linear layout view is not being updated. Can some one pls help.
public class child extends Activity {
private Intent intent;
private LinearLayout layout;
private LayoutInflater linflater;
private int i =0;
private Cursor cr;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.child);
layout = (LinearLayout)findViewById(R.id.layout);
Button addBtn = (Button)findViewById(R.id.AddButton);
Button remBtn = (Button)findViewById(R.id.RemoveButton);
intent = new Intent(this,login.class);
layout = (LinearLayout) findViewById(R.id.mylayout1);
linflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//Check the database if there are any entries available. If available, then
//list them on the main screen
final myDBAdapter mydb = new myDBAdapter(getApplicationContext());
mydb.open();
cr = mydb.GetMyData();
if(cr.getCount()>0)
{
cr.moveToFirst();
for (int i=0;i<cr.getCount();i++)
{
cr.moveToPosition(i);
buildList(cr.getString(1),cr.getString(2));
}
}
//Start the login activity which will return the newly added baby name
addBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivityForResult(intent, 1001);
}
});
//Remove all the entries from Database
remBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(cr.getCount()>0)
{
cr.moveToFirst();
for (int i=0;i<cr.getCount();i++)
{
Toast.makeText(getApplicationContext(), cr.getString(1),
Toast.LENGTH_LONG).show();
mydb.RemoveEntry(cr.getString(1));
cr.moveToPosition(i);
}
}
}
});
mydb.close();
}
private void buildList(final String bname,String bsex)
{
final View customView = linflater.inflate(R.layout.child_view,
null);
TextView tv = (TextView) customView.findViewById(R.id.TextView01);
//tv.setId(i);
tv.setText(bname);
tv.setTextColor(getResources().getColor(R.color.black));
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myDBAdapter mydb = new myDBAdapter(getApplicationContext());
mydb.open();
if (mydb.RemoveEntry(bname)>0)
{
Toast.makeText(getApplicationContext(), "Row deleted",
Toast.LENGTH_LONG).show();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WHAT IS REQUIRED HERE TO UPDATE THE VIEW???
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
else
{
Toast.makeText(getApplicationContext(), "Row not deleted",
Toast.LENGTH_LONG).show();
}
}
});
layout.addView(customView);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == 1001)
{
if(resultCode == RESULT_OK)
{
Bundle extras = data.getExtras();
buildList(extras.getString("bname"),extras.getString("bsex"));
}
}
}
}
Hmm I'm also trying to get this to work, Have you tried looking at maybe refreshing the LinearLayout every say 5 seconds using a game loop? This may prove to be useful as it helped me with my problem http://aubykhan.wordpress.com/2010/04/25/android-game-programming-the-game-loop/
You may also be able to call onCreate(Bundle) function again while this is a terrible terrible way to do this it will work.