java custom view in flutter - java

I have a custom view, written in Java and want to use it in my flutter project. Is it possible to convert it to dart-native code or use it as a java class in flutter?
Custom view is quite complex and I am not very experienced in dart language, so would be great to have it either converted to dart or use it as it is

Step 1 : You have to write method channel into dart code:
static Future<void> initSupport({
String? url,
String? appId,
String? clientId,
String? id,
}) async {
await _channel.invokeMethod<void>('initSupport', {
'url': url,
'appId': appId,
'clientId': clientId,
'id': id,
});
}
You have to write into your view where you want to open java view to init this method channel
After this, you have to open your project in android studio
Step 2: Check the below code to get method channel from dart
class MainActivity: FlutterFragmentActivity() {
override fun onNewIntent(intent : Intent){
super.onNewIntent(intent)
setIntent(intent)
}
private val CHANNEL = "channelname"
override fun configureFlutterEngine(#NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
if(call.method == "initSupport"){
initSupport(call)
result.success(true)
}
}
}
Step 3: method of init is
fun initSupport(call: MethodCall){
val url = call.argument<String>("url") ?: "" // here is your dart data
val appId = call.argument<String>("appId") ?: ""
val clientId = call.argument<String>("clientId") ?: ""
val id = call.argument<String>("id") ?: "1"
// You can init your view here like below
Toast.makeText(this,"hello from native", Toast.LENGTH_SHORT).show()
}

Related

Upload Image/ImageProxy class to a Server in Android with HTTP2

I am trying to capture an ImageCapture with the camera and upload to an API without saving it in the device; but I am unable to find any straightforward way to upload the Image class. And, whether I should convert the image to bytesarray and POST it into the API where it can be handled. What I need are some resources or examples on how to do. Here is my code, where uploadFile is going to be the function where we'll pass an ImageProxy object:
...
val imgCap = ImageCapture(imageCaptureConfig)
findViewById<View>(R.id.screen).setOnClickListener { _: View? ->
imgCap.takePicture(object : ImageCapture.OnImageCapturedListener() {
override fun onCaptureSuccess(image: ImageProxy, rotationDegrees: Int) {
Toast.makeText(baseContext, "Image Captured", Toast.LENGTH_SHORT).show()
uploadFile(image)
super.onCaptureSuccess(image, rotationDegrees)
}
})
}
...

Kotlin multi platform flow block convert to custom wrapper flow use for ios

I have a kotlin multi platform project which contains apollo graphql api
in this project i have BaseRepository Class and in this class there is a method to execute query or mutations
suspend fun <D : Query.Data> executeQuery(query: Query<D>): ApolloResponse<D> {
val response = getApolloClient().query(query).execute()
checkOperation(response)
return response
}
suspend fun <D : Mutation.Data> executeMutation(mutation: Mutation<D>): ApolloResponse<D> {
val response = getApolloClient().mutation(mutation).execute()
checkOperation(response)
return response
}
For example i want to use this method in Some repository like this
class HelpRepository : BaseRepository() {
fun test(request: AddFeedBackRequest) = flow {
val feedBackType = if (request.type == AddFeedBackType.Bug) {
FeedbackType.BUG
} else {
FeedbackType.FEEDBACK
}
val input = AddFeedbackInput(request.note, Optional.presentIfNotNull(feedBackType))
emit(true)
val mutation = AddFeedbackMutation(input)
val response = executeMutation(mutation)
emit(false)
}
}
when i add the flow scope i shouldn't be had to convert this method to a suspend function
i dont want to use suspend function because of ios application. When i use suspend function its convert "Kotlinx_coroutines_coreFlowCollector" in xcode
so i found a wrapper function like this
fun <T> Flow<T>.asCommonFlow(): CommonFlow<T> = CommonFlow(this)
class CommonFlow<T>(private val origin: Flow<T>) : Flow<T> by origin {
fun listen(block: (T) -> Unit): Closeable {
val job = Job()
onEach {
block(it)
}.launchIn(CoroutineScope(Dispatchers.Main + job))
return object : Closeable {
override fun close() {
job.cancel()
}
}
}
}
when i use this wrapper with single variable it works exactly what i want in xcode.
but in functions i couldn't find a proper way to do this
i need a wrapper like
= commonFlow {
}
instead of this
= flow {
}
to use this method as a commonFlow wrapper
Can you help me ?
We have pretty much the same thing in one of our projects. We have a extension function that converts the regular flow to a "common" flow so it can be used in both Android and iOS.
You can created flow like always, and wrap it at the end.
fun <T> Flow<T>.wrap(): CommonFlow<T> = CommonFlow(this)
class HelpRepository : BaseRepository() {
fun test(request: AddFeedBackRequest) = flow {
val feedBackType = if (request.type == AddFeedBackType.Bug) {
FeedbackType.BUG
} else {
FeedbackType.FEEDBACK
}
val input = AddFeedbackInput(request.note, Optional.presentIfNotNull(feedBackType))
emit(true)
val mutation = AddFeedbackMutation(input)
val response = executeMutation(mutation)
emit(false)
}
}.wrap()

Add a Intent in a class

I need to start a new activity to show an image in Fullscreen and my Intent is in a class but outside my main class.
class PhotoItem(val user: String, val send: String, val timestamp: Long, val country: String): Item<GroupieViewHolder>(){
override fun bind(viewHolder: GroupieViewHolder, position: kotlin.Int) {
viewHolder.itemView.textView10.text = user
viewHolder.itemView.textView13.text = timestamp.toString()
viewHolder.itemView.textView14.text = country
val uri = send
val targetImageView = viewHolder.itemView.selectphoto_imageview
val targetImageViewFullScreen = viewHolder.itemView.fullscreen
Picasso.get().load(uri).into(targetImageView)
viewHolder.itemView.setOnClickListener{v : View ->
v.getContext().startActivity(Intent(v.getContext(), FullscreenPhoto::class.java))
}
}
override fun getLayout(): kotlin.Int {
return R.layout.photo_from_row
}
}
So I found this line : v.getContext().startActivity(Intent(v.getContext(), FullscreenPhoto::class.java)) because I can't create a basic Intent : val intent = Intent(this,Home::class.java)startActivity(intent)
And I need to have the val uri for load the image into my Image view
thank you in advance.
I guess the issue is that startActivity is not available in PhotoItem
So change GroupieViewHolder class and add activity in constructor like this:
class GroupieViewHolder(val activity: Activity, /* other arguments */)
Now use that field in bind of PhotoItem as below:
override fun bind(viewHolder: GroupieViewHolder, position: kotlin.Int) {
// other codes.........
viewHolder.itemView.setOnClickListener{v : View ->
// using activity field for startActivity
viewHolder.activity.startActivity(Intent(v.getContext(), FullscreenPhoto::class.java))
}

Camera2 - "Must be called from main thread of fragment host" when changing fragment

I'm trying to change the fragment after an image is taken with the following code Google Sample - Camera2Basic.
I've implemented a callback to my MainActivity at line 839 of the above sample. However when I am trying to traverse to a different activity from that callback I receive the following exception:
java.lang.IllegalStateException: Must be called from main thread of
fragment host
Does anyone know anyway around this?
I have the working code in Kotlin
You must replace this callback with:
val captureCallback = object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(session: CameraCaptureSession,
request: CaptureRequest,
result: TotalCaptureResult) {
sendBackResult(mFile)
}
}
mCaptureSession!!.capture(captureBuilder.build(), captureCallback, mBackgroundHandler)
} catch (e: CameraAccessException) {
e.printStackTrace()
}
sendBackResult method is as follows:
private fun sendBackResult(resultFile: File?) {
val fileUri = Uri.fromFile(resultFile)
val dataIntent = Intent()
dataIntent.data = fileUri
dataIntent.putExtra("isFront", isFrontCamera)
activity!!.setResult(Activity.RESULT_OK, dataIntent)
activity!!.finish()
}

Observable.zip issues

I download posts from two pages from Facebook using Retrofit and RxJava. I want to download them by Observable.zip but I'm getting onError : An operation is not implemented: not implemented.
My code:
var fb1 = dataManager.getPosts(ApplicationConstants.FACEBOOK_PAGE_1, ApplicationConstants.FACEBOOK_APP_TOKEN, "70")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
var fb2 = dataManager.getPosts(ApplicationConstants.FACEBOOK_PAGE_2, ApplicationConstants.FACEBOOK_APP_TOKEN, "70")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
val observableZip : Observable<PostList> = Observable.zip(fb1,fb2, object: Function<PostList, PostList>, BiFunction<PostList, PostList, PostList> {
override fun apply(t: PostList): PostList {
}
override fun apply(t1: PostList, t2: PostList): PostList {
}
})
compositeDisposable.add(observableZip.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(
{result -> posts.addAll(result.data)},
{t : Throwable? -> Log.d("TAG",t?.message) },
{view.setAdapter(posts)
view.hideProgressBar()}
))
I not exactly understend how to make Observable.zip as examples in the Internet are not clearly explained.
Q: How to change my code to make Observable.zip working ?
Your zip should look like this:
val observableZip : Observable<PostList> = Observable.zip(fb1,fb2, object : BiFunction<PostList, StriPostList, PostList> {
override fun apply(t1: PostList, t2: PostList): PostList {
// do the zipping
}
})
There is no zip with parameters of type Function, and BiFunction. Only the list of observables and then a BiFunction (or, alternatively a single ObservableSource and a normal Function)
It's important to use the BiFunction from Rx, so make sure you're using import io.reactivex.functions.BiFunction not java.util.function.BiFunction

Categories

Resources