Please i have been trying this for weeks now. I have a fragment that displays notifications. But it time i click on the notification my app crashes. it points me the line below Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(imageView)
and it says: java.lang.IllegalArgumentException: Path must not be empty
From logcat, using picasso seems to be the problem but i am new to programming and i have no idea what exacty to do. Please help me. Thank you
Below is the complete code for my notificationAdapter
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(mContext).inflate(R.layout.notifications_item_layout , parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val notification = mNotification[position]
if(notification.getText().equals("Admirers you")){
holder.text.text = "Admirers you"
}
else if(notification.getText().equals("Liked your post")){
holder.text.text = "Liked your post"
}
else if (notification.getText().contains("commented:")){
holder.text.text = notification.getText().replace("commented:", "commented: ")
}
else{
holder.text.text = notification.getText()
}
userInfo(holder.profileImage, holder.fullname, notification.getUserId())
if(notification.isIsPost()){
holder.postImage.visibility = View.VISIBLE
getPostImage(holder.postImage, notification.getPostId())
}
else{
holder.postImage.visibility = View.GONE
}
holder.itemView.setOnClickListener {
if(notification.isIsPost()){
val editor = mContext.getSharedPreferences("PREFS", Context.MODE_PRIVATE).edit()
editor.putString("postId", notification.getPostId())
editor.apply()
(mContext as FragmentActivity).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, PostDetailsFragment()).commit()
}
else{
val editor = mContext.getSharedPreferences("PREFS", Context.MODE_PRIVATE).edit()
editor.putString("profileId", notification.getUserId())
editor.apply()
(mContext as FragmentActivity).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, ProfileFragment()).commit()
}
}
}
override fun getItemCount(): Int {
return mNotification.size
}
inner class ViewHolder(#NonNull itemView: View) : RecyclerView.ViewHolder(itemView)
{
var postImage: ImageView
var profileImage : CircleImageView
var fullname : TextView
var text : TextView
init {
postImage = itemView.findViewById(R.id.notification_post_image)
profileImage = itemView.findViewById(R.id.notifications_profile_image)
fullname = itemView.findViewById(R.id.fullname_notification)
text = itemView.findViewById(R.id.comment_notification)
}
}
private fun userInfo(imageView: ImageView, fullname: TextView, publisherId:String)
{
val usersRef =
FirebaseDatabase.getInstance().reference
.child("Users")
.child(publisherId)
usersRef.addValueEventListener(object : ValueEventListener
{
override fun onDataChange(p0: DataSnapshot)
{
if (p0.exists())
{
val user = p0.getValue(User::class.java)
Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(imageView)
fullname.text = user.getfullname()
}
}
override fun onCancelled(p0: DatabaseError) {
}
})
}
private fun getPostImage(imageView: ImageView, postID:String)
{
val postRef =
FirebaseDatabase.getInstance()
.reference.child("Posts")
.child(postID)
postRef.addValueEventListener(object : ValueEventListener
{
override fun onDataChange(p0: DataSnapshot)
{
if (p0.exists()) {
val post = p0.getValue<Post>(Post::class.java)
Picasso.get().load(post!!.getpostimage()).placeholder(R.drawable.profile)
.into(imageView)
}
}
override fun onCancelled(p0: DatabaseError) {
}
})
}
}
And also my notification fragment
<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"
tools:context="Fragments.NotificationsFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/app_bar_layout_notifications"
android:background="#color/white">
<androidx.appcompat.widget.Toolbar
android:id="#+id/notifications_toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="4dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="#android:color/white">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Notifications"
android:textSize="18sp"
android:maxLines="1"
android:textStyle="bold"
android:textColor="#android:color/black"
android:layout_centerVertical="true"/>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_notifications"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:layout_below="#+id/app_bar_layout_notifications">
</androidx.recyclerview.widget.RecyclerView>
Then in case you need more info, here's my notifications item layout. Thank you
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="6dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/notifications_profile_image"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/profile">
</de.hdodenhof.circleimageview.CircleImageView>
<LinearLayout
android:layout_toEndOf="#+id/notifications_profile_image"
android:layout_toStartOf="#+id/notification_post_image"
android:layout_centerVertical="true"
android:layout_marginStart="5dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/fullname_notification"
android:textStyle="bold"
android:textColor="#color/teal_200"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="#+id/comment_notification"
android:textStyle="bold"
android:textColor="#color/teal_200"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<ImageView
android:id="#+id/notification_post_image"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentEnd="true">
</ImageView>
I don't know Picasso, so I can't tell you what the problem is*. (I don't even know Android, which I guess this is for.) But since you're new to programming, it seems to me that what you need to know is how to find out the problem for yourself — how to debug — so here are some hints that I hope will help.
You've done the right thing in starting with the logs; if you have an exception with a stack trace, that's always helpful in narrowing down the problem. But your case hasn't narrowed it down enough, because that one line is doing many different things. So the simplest thing to try would be to split that line up — then the stack trace's line number will narrow it down more finely.
You could simply wrap the line, e.g.:
Picasso.get()
.load(user!!.getImage())
.placeholder(R.drawable.profile)
.into(imageView)
Then you'll be able to tell which of those main operations triggered the exception. (Of course, the operation that gave the exception might not be the one you need to change — but either way you need to understand the problem before you can fix it.)
If that's not enough, then there are several approaches you could take. But the one I usually end up falling back on is the most general: logging. Whether you're working on a desktop app, a mobile app, a web app, a microservice, a stand-alone app, or whatever, there's almost always a way to print out some text in such a way that you can see it on screen or in a file. As I said, I don't know Android, but this question seems to show how you can do that; in other environments, you might use one of several logging libraries (java.util.logging, log4j…), or just the basic println(). But however you do it, there's bound to be a way you can see some of the intermediate values — and being able to see what's going on is always valuable when debugging.
You could try printing out the user (or, if that doesn't have a simple string representation, their name or something else that might give you a clue). Then the image, ditto. The the results of the load() call. And so on. Of course, that means restructuring your code a bit, e.g.:
val picasso = Picasso.get()
println("picasso = $picasso")
println("user = $user")
val image = user!!.getImage()
println("image = $image")
val loaded = picasso.load(image)
println("loaded = $loaded")
println("profile = ${R.drawable.profile}")
val placeholder = loaded.placeholder(R.drawable.profile)
println("placeholder = $placeholder")
println("imageView = $imageView")
placeholder.into(imageView)
(Substituting whatever logging method works in your case. I'm overdoing it here, of course. But I hope you get the idea.)
For the record, Kotlin's also() gives a way of doing the above without having to name all the temporary variables, or split up the chain of calls:
Picasso.get()
.also{ println("picasso = $it") }
.also{ println("user = $user") }
.load(user!!.getImage().also{ println("image = $it") } )
.also{ println("loaded = $it") }
.placeholder(R.drawable.profile.also{ println("profile = $it") })
.also{ println("placeholder = $it") }
.into(imageView.also{ println("imageView = $it") })
However, that can get unwieldy pretty quickly, so I wouldn't normally recommend it.
Either way, in all likelihood one of the values you print out won't be what you expect, or you'll be able to spot something that doesn't look right, and that will give you enough info to identify the problem — or at least, to direct your attention to some other part of the code that you can then debug in the same way.
Once you've fixed the problem and the code is behaving as expected, you can remove the logging. However, it's often better to leave some logging code in. (Especially if you're using a logging library that lets you set different levels, so you can log this at a low level that you won't normally get to see.) Then, when you need to track down some other problem in the code, it's much easier to see what's going on.
(* From the exception message, I'd suspect an issue with the user!!.getImage() part. But that's just a blind guess.)
I am trying to update the recyclerView adapter in the observe response of live data object but it is not updating the UI rather if I debug it, it starts updating the UI.
Looks like adding a delay make it work or reassigning the recyclerView items adapter also works but I didn't understand why is the notifyDataSetChanged or notifyItemRangeChanged is not working
following is the code I am using
adapter = MyAdapter(listOf())
binding.recyclerView.adapter = adapter
viewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
viewModel.data.observe(this, {
adapter.setData(it)
// This updates the UI, but this is not the right way to do so
//binding.recyclerViewData.adapter = adapter
})
Adapter class where I update the data
fun setData(data: MutableList<DataModelRoom>) {
this.data= data
notifyItemRangeChanged(0, data.size)
}
ViewModel part of the code
var data: MutableLiveData<MutableList<DataModel>> = MutableLiveData()
/* This is part of init method */
viewModelScope.launch {
Amplify.Hub.subscribe(HubChannel.DATASTORE) { event ->
if (event.name == DataStoreChannelEventName.READY.toString()) {
isAmplifyDataReady.postValue(true)
data.postValue(repository.getDataFromAmplify())
}
Log.i(Logging.TAG_AMPLIFY, "event: $event")
}
/* Starting the DataStore Syncing */
Amplify.DataStore.start(
{ Log.i(Logging.TAG_AMPLIFY, "DataStore started") },
{ Log.e(Logging.TAG_AMPLIFY, "Error starting DataStore", it) }
)
}
Layout part of the recyclerView
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="152dp"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textViewView" />
I think you're over complicating the issue. Use a ListAdapter<T, K> (included with the platform and call adapter.submitList(pass_the_new_list_here) and have the (required) DiffUtil.Callback handle the differences and update what's needed.
Hello I wonder how to set regex in EditText with Android two way binding
my regex
val VALID_PASSWOLD_REGEX_ALPHA_NUM: Pattern = Pattern.compile("^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$#$!%*#?&])[A-Za-z[0-9]$#$!%*#?&]{8,32}$")
my viewModel
val passwordText = MutableLiveData<String>("")
my xml
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#null"
android:onTextChanged="#{(text, start, before, count) -> signUpViewModel.onPasswordChanged(text)}"
android:hint="#string/sign_up_password"
android:text="#={signUpViewModel.passwordText}"
android:textSize="22dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/name_text" />
My short thought is that it should be received from onTextChange and processed, but I can't think of a better way, so I ask this question
Could you please introduce me another way?
I just did it using android:onTextChanged Thanks
In my project, we have developed the structure such as we can run the individual test cases from the test files where as for a complete BVT, we have to run the same cases using testng xml that too in the proper sequence(skipping the current test, if previous test fails).
However when we tried to run the scenario with this approach, we are either able to run all the scenario(not able to skip the tests and all of them failing if first fails) or none of them runs at all.
Please have a look at the below code snippet similar to my project code and let me know if I am missing something here.
First Test :
import org.testng.Assert;
import org.testng.annotations.Test; /** * Hello world! * */
public class App {
#Test(groups = "FirstGroup") public void testCase1() {
boolean x = true;
System.out.println("Test Case 1");
Assert.assertEquals(x, true);
}
}
Second Test :
import org.testng.Assert;
import org.testng.annotations.Test;
public class App2 {
#Test(groups = "SecondGroup") public void testCase2() {
boolean x = true;
System.out.println("Test Case 2");
Assert.assertEquals(x, false);
}
}
testng.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="softwaretestingmaterial">
<test name="testngTest">
<classes>
<class name="Project.Test.Test.App" />
</classes>
</test>
<test name="testngTest2">
<groups>
<run>
<include name="Project.Test.Test.App" />
<include name="Project.Test.Test.App2" />
</run>
<dependencies>
<group name="SecondGroup" depends-on="FirstGroup"></group>
</dependencies>
</groups>
<classes>
<class name="Project.Test.Test.App2" />
</classes>
</test>
</suite>
You might wanna try specifying these dependencies as annotations shown as below, instead of specifying them in the TestNg.xml file.
import org.testng.Assert;
import org.testng.annotations.Test;
public class App2 {
**#Test(groups = "SecondGroup", dependsOnMethods = { "testCase1" })**
public void testCase2() {
boolean x = true;
System.out.println("Test Case 2");
Assert.assertEquals(x, false);
}
}
Updated Answer:
Yeah you are right about that.
It seems that there is no easy way to achieve this. However, I did some reading and found this:
https://www.seleniumeasy.com/testng-tutorials/skip-test-in-testng
You can couple this mechanism with ITestListener to skip subsequent tests if priority tests fails. Although I am not very certain how that will work but a Logic for the same can be designed.
Your Last option would be to use an ITestListener in combination with an Excel Sheet that stores the Pass/Fail status of your Priority test and skips tests accordingly
good morning i would like to scroll a large image in my Android app the size of my image is 800 * 3782 px
every time i get error of memory the size of the image is 1.7Mb with 72 dpi resolution.
this is the xml :
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<HorizontalScrollView
android:id="#+id/horizontalScrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</ScrollView>
</HorizontalScrollView>
</LinearLayout>
this the java class:
public class About extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.about);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
Resources res = getResources();
BitmapDrawable bitmap = (BitmapDrawable) res.
getDrawable(R.drawable.aboutscroll);
int imgW = bitmap.getIntrinsicWidth();
int imgH = bitmap.getIntrinsicHeight();
iv.setImageDrawable(bitmap);
ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) iv.getLayoutParams();
params.width = imgW;
params.height = imgH;
}
}
i got this trace of error :
08-27 09:51:10.175: E/AndroidRuntime(1578): FATAL EXCEPTION: main
08-27 09:51:10.175: E/AndroidRuntime(1578): java.lang.OutOfMemoryError
08-27 09:51:10.175: E/AndroidRuntime(1578): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
08-27 09:51:10.175: E/AndroidRuntime(1578): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502)
if someone can help me please.
"Out of memory error" means image file is too big.. if you reduce, then no more error. :)