I am building a Android app in Java, use a Enum variable in a .setText scenario for a XML TextView, i fully understand my Enum is in the wrong data type, but i need your help to work out a alternative to this.
The code where i'm using the setText:
package com.mastermind;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
public class Guess_database extends Activity {
public ArrayList<Guess> guess_list;
public static int guess_counter = 0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.guess_layout);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (Guess g : guess_list) {
View stub = inflater.inflate(R.layout.guess_stub, null);
((TextView) stub.findViewById(R.id.guess)).setText(g.v1 + ", "+ g.v2);
((TextView)stub.findViewById(R.id.guess_positions)).setText(g.c1);
}
}
}
And here is the class for my Enum variable:
package com.mastermind;
import java.io.Serializable;
public class Guess implements Serializable
{
static int v1, v2, v3, v4;
public static GuessStatus c1,c2, c3, c4;
enum GuessStatus
{
CORRECT,
WRONG,
CORRECT_WRONG_PLACE;
}
}
Any help will be appreciated.
((TextView)stub.findViewById(R.id.guess_positions)).setText(g.c1.toString());
Related
I'm trying to implement the custom launchFragmentInHiltContainer() method in a Java project, and I've already gone through all the hoops of setting up kotlin and refactoring the reified parameters. However, when I try to compile the project, I am greeted by this puzzling error:
C:\Users\jedwa\AndroidStudioProjects\AppName\app\src\androidTest\java\com\example\appname\MainActivityTest.java:55: error: cannot access Hilt_FragmentPersonalDetails
HiltExtKt.launchFragmentInHiltContainer(FragmentPersonalDetails.class);
^
class file for com.example.appname.fragments.Hilt_FragmentPersonalDetails not found
FragmentPersonalDetails is a hilt-enabled fragment and works fine in production code. What is strange is that replacing FragmentPersonalDetails.class with a NonHiltFragment.class will allow the project to compile just fine.
What it will not do, however is stop a runtime error from occurring, which may be related. On replacing FragmentPersonalDetails with NonHiltFragment, I get:
java.lang.RuntimeException: Hilt test, MainActivityTest, is missing generated file: com.example.appname.MainActivityTest_TestComponentDataSupplier. Check that the test class is annotated with #HiltAndroidTest and that the processor is running over your test.
which I have seen before, except this time I most definitely do have #HiltAndroidTest on my test class. I've finally hit the point where the error is internal enough that I have no idea how to go about fixing it, though it seems like a dependency error of some sort. Files provided below for reference.
The hilt-enabled FragmentPersonalDetails
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import com.example.atease.R;
import com.example.atease.databinding.FragmentPersonalDetailsBinding;
import com.example.atease.viewmodels.LoginViewModel;
import dagger.hilt.android.AndroidEntryPoint;
#AndroidEntryPoint
public class FragmentPersonalDetails extends Fragment {
private FragmentPersonalDetailsBinding binding;
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentPersonalDetailsBinding.inflate(inflater, container, false);
binding.setLifecycleOwner(this);
NavController navController = NavHostFragment.findNavController(this);
ViewModelStoreOwner store = navController.getViewModelStoreOwner(R.id.login_graph);
binding.setViewModel(new ViewModelProvider(store).get(LoginViewModel.class));
return binding.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.nextButton.setOnClickListener(view1 ->
NavHostFragment.findNavController(FragmentPersonalDetails.this)
.navigate(R.id.action_FragmentPersonalDetails_to_FragmentEmploymentDetails));
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
The test class that won't compile
import androidx.test.espresso.IdlingRegistry;
import androidx.test.espresso.accessibility.AccessibilityChecks;
import com.example.atease.fragments.SecondFragment;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import javax.inject.Inject;
import dagger.hilt.android.testing.HiltAndroidRule;
import dagger.hilt.android.testing.HiltAndroidTest;
/**
* Instrumented test, which will execute on an Android device.
*
* #see Testing documentation
*/
#HiltAndroidTest
public class MainActivityTest {
#Inject DataBindingIdlingResource bindingIdlingResource;
#BeforeClass
public static void enableAccessibility() {
AccessibilityChecks.enable().setRunChecksFromRootView(true);
}
#Before
public void init() {
hiltRule.inject();
IdlingRegistry.getInstance().register(bindingIdlingResource);
}
#After
public void tearDown() {
IdlingRegistry.getInstance().unregister(bindingIdlingResource);
}
#Rule
public HiltAndroidRule hiltRule = new HiltAndroidRule(this);
//cycles through the nav-bar
#Test
public void testNavbar() {
HiltExtKt.launchFragmentInHiltContainer(SecondFragment.class);
}
}
My implementation of launchFragmentinHiltContainer. The only difference is that I took out the reified parameter types and added the extra class parameter, in order to be able to reference the methods from Java.
import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
import androidx.annotation.StyleRes
import androidx.core.util.Preconditions
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import kotlinx.coroutines.ExperimentalCoroutinesApi
#JvmOverloads
#ExperimentalCoroutinesApi
inline fun <T : Fragment> launchFragmentInHiltContainer(
fragmentType: Class<T>,
fragmentArgs: Bundle? = null,
#StyleRes themeResId: Int = R.style.FragmentScenarioEmptyFragmentActivityTheme,
crossinline action: Fragment.() -> Unit = {}
) {
val startActivityIntent = Intent.makeMainActivity(
ComponentName(
ApplicationProvider.getApplicationContext(),
HiltTestActivity::class.java
)
).putExtra("androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY",
themeResId)
ActivityScenario.launch<HiltTestActivity>(startActivityIntent).onActivity { activity ->
val fragment: Fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
Preconditions.checkNotNull(fragmentType.classLoader),
fragmentType.name
)
fragment.arguments = fragmentArgs
activity.supportFragmentManager
.beginTransaction()
.add(android.R.id.content, fragment, "")
.commitNow()
fragment.action()
}
}
#JvmOverloads
#ExperimentalCoroutinesApi
inline fun <T : Fragment> launchFragmentInHiltContainer(
fragmentType: Class<T>,
fragmentArgs: Bundle? = null,
#StyleRes themeResId: Int = R.style.FragmentScenarioEmptyFragmentActivityTheme,
factory: FragmentFactory,
crossinline action: Fragment.() -> Unit = {}
) {
val startActivityIntent = Intent.makeMainActivity(
ComponentName(
ApplicationProvider.getApplicationContext(),
HiltTestActivity::class.java
)
).putExtra("androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY",
themeResId)
ActivityScenario.launch<HiltTestActivity>(startActivityIntent).onActivity { activity ->
activity.supportFragmentManager.fragmentFactory = factory
val fragment: Fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
Preconditions.checkNotNull(fragmentType.classLoader),
fragmentType.name
)
fragment.arguments = fragmentArgs
activity.supportFragmentManager
.beginTransaction()
.add(android.R.id.content, fragment, "")
.commit()
fragment.action()
}
}
Just rewrite the function in Java. I changed the signature to match the original FragmentScenario.launchInContainer.
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.test.core.app.ActivityScenario;
import androidx.test.core.app.ApplicationProvider;
import java.util.Objects;
public class HiltHelper {
public static void launchFragmentInHiltContainer(Class<? extends Fragment> fragmentClass, Bundle fragmentArgs, #StyleRes int themeResId) {
Intent intent = Intent.makeMainActivity(new ComponentName(ApplicationProvider.getApplicationContext(), HiltTestActivity.class))
.putExtra("androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY", themeResId);
ActivityScenario.launch(intent)
.onActivity(activity -> {
Fragment fragment = ((AppCompatActivity) activity).getSupportFragmentManager().getFragmentFactory()
.instantiate(Objects.requireNonNull(fragmentClass.getClassLoader()), fragmentClass.getName());
fragment.setArguments(fragmentArgs);
((AppCompatActivity) activity).getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, fragment, "")
.commitNow();
});
}
}
I've spent som time trying to fix it, but my app works fine except for the images that don't load into my recyclerview. I tried with and without firebase database to get the images but in both case i don't get them.
However i get all my texts so i don't understand where the problem comes from. I searched for quite a time and didn't see anything that i didn't do in other tutorials/helps.
In my logcat i get the following errors :
2021-05-27 20:31:25.445 22716-22716/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2021-05-27 20:31:25.447 22716-22716/? E/Zygote: accessInfo : 1
And in the case of firebase Database i get the previous errors plus this one :
E/RecyclerView: No adapter attached; skipping layout
I put here my code so you can check if you need
Activity class :
package fr.balizok.pizzaapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import fr.balizok.pizzaapplication.adapter.PizzaAdapter;
public class MainActivity extends AppCompatActivity {
List<PizzaModel> pizzaList = new ArrayList<PizzaModel>();
RecyclerView recyclerViewPizzas;
PizzaAdapter pizzaAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pizzaList.add(new PizzaModel(
"Margherita",
"Sauce tomate, Mozarella",
"5.80€",
"https://cdn.pixabay.com/photo/2020/06/08/16/49/pizza-5275191_960_720.jpg"));
pizzaList.add(new PizzaModel(
"Savoyarde",
"Sauce tomate, Mozarella, Pomme de terre, Fromage",
"10.20€",
"https://cdn.pixabay.com/photo/2017/11/23/16/57/pizza-2973200_960_720.jpg"));
pizzaList.add(new PizzaModel(
"Poulet pesto",
"Sauce tomate, Mozarella, Poulet, Pesto",
"8.50€",
"https://cdn.pixabay.com/photo/2016/06/08/00/03/pizza-1442945_960_720.jpg"));
pizzaList.add(new PizzaModel(
"4 Saisons",
"Sauce tomate, Mozarella, Olive, Basilic, Jambon, Champignons, Artichaut",
"9.60€",
"https://cdn.pixabay.com/photo/2016/06/08/00/03/pizza-1442946_960_720.jpg"));
recyclerViewPizzas = findViewById(R.id.recyclerViewPizzas);
recyclerViewPizzas.setHasFixedSize(true);
recyclerViewPizzas.setLayoutManager(new LinearLayoutManager(this));
pizzaAdapter = new PizzaAdapter(MainActivity.this, pizzaList);
recyclerViewPizzas.setAdapter(pizzaAdapter);
recyclerViewPizzas.addItemDecoration(new PizzaItemDecoration());
}
}
Adapter class :
package fr.balizok.pizzaapplication.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.List;
import fr.balizok.pizzaapplication.PizzaModel;
import fr.balizok.pizzaapplication.R;
public class PizzaAdapter extends RecyclerView.Adapter<PizzaAdapter.ViewHolder>{
Context context;
List<PizzaModel> pizzaList;
public PizzaAdapter(Context context, List<PizzaModel> pizzaList) {
this.context = context;
this.pizzaList = pizzaList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.menu_pizza_design,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull PizzaAdapter.ViewHolder holder, int position) {
PizzaModel currentPizza = pizzaList.get(position);
holder.pizza_name.setText(currentPizza.getName());
holder.ingredients.setText(currentPizza.getIngredients());
holder.price.setText(currentPizza.getPrice());
Glide.with(context).load(currentPizza.getImageURL()).into(holder.pizza_image);
}
#Override
public int getItemCount() {
return pizzaList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView pizza_image;
TextView pizza_name, ingredients, price;
public ViewHolder(#NonNull View itemView) {
super(itemView);
pizza_image = itemView.findViewById(R.id.pizza_image);
pizza_name = itemView.findViewById(R.id.pizza_name);
ingredients = itemView.findViewById(R.id.ingredients);
price = itemView.findViewById(R.id.price);
}
}
}
Hope you can help me, thank you in advance !
I follow your code and make it demo its resolved by using Picasso library.
Try this one I hope it would be helpful to you.
Picasso.get()
.load(currentPizza.getImageURL())
.resize(600, 200) // resizes the image to these dimensions (in pixel) if you want
.centerInside()
.into(holder.pizza_image);
I'm importing a windows pairs game (writen in java) to android
but when I run this I can see no buttons...
(currently my code does not seems nice cuz I shoud deliver it to uni fast)
what is going wrong here?
package mgh;
import mgh.mgh.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.RelativeLayout;
public class mghActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new mghActivity();
}
public int numberOfClickes=0;
public card continueCard=null;
public int killedCards=0;
public card selectedCard=null;
public long spentTime=0;
public card[][] card=new card[4][4];
public void mghActivity(){
setTitle("pairs");
//setVisible(true);
//setSize(500,500 );
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AbsoluteLayout lay=new AbsoluteLayout(this);
int[] clr=new int[8];
short[] timesUsed=new short[8];
for (int i=0;i<=7;i++)
timesUsed[i]=0;
for (int i=0;i<=7;i++)
clr[i]= Color.rgb(((int)(Math.random()*2))*255,
((int)(Math.random()*2))*255,
((int)(Math.random()*2))*255);
for (int i=0;i<=3;i++)
for (int j=0;j<=3;j++){
int rnd=0;
while (timesUsed[rnd]>=2)
rnd=(int)(Math.random()*8)%8;
timesUsed[rnd]++;
card[i][j]=new card(this,clr[rnd]);
//card[i][j].setEnabled(false);
//AbsoluteLayout.LayoutParams mparams=new AbsoluteLayout.LayoutParams
//(lay.getWidth()/4,lay.getHeight()/4,(lay.getWidth()/4)*i,(lay.getWidth()/4)*j);
int m=40;
AbsoluteLayout.LayoutParams mparams=new AbsoluteLayout.LayoutParams
(m,m,m*i,m*j);
lay.addView(card[i][j],mparams);
card[i][j].setOnClickListener(this);
}
setContentView(lay);
}
public void onClick(View arg0) {
}
}
class card extends Button {///not completed
public int color;
public card(Context context,int color){
super(context);
this.color=color;
setBackgroundColor(color);
}
}
In method onCreate, you just new mghActivity but did not call the the method mghActivity. And mghActivity is not a constructor. You shall remove the void before mghActivity. Then it will be a constructor and called automatically. Even so, I will not recommend creating an Activity like this.
In Android, I am trying to override the toString() of the ParseUser for use in my listview, using
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import java.util.List;
/**
* A simple {#link Fragment} subclass.
*/
public class ExampleFragment extends Fragment {
public ExampleFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_example, container, false);
final ListView listView = (ListView) rootView.findViewById(R.id.exampleListView);
ParseQuery query = User.getQuery();
query.findInBackground(new FindCallback<User>() {
public void done(List<User> objects, ParseException e) {
if (e == null) {
// The query was successful.
listView.setAdapter(new ArrayAdapter<User>(rootView.getContext(), android.R.layout.simple_list_item_1, objects));
for (User user : objects) {
Log.i("AppInfo", "Added " + user.toString());
}
} else {
// Something went wrong.
}
}
});
return rootView;
}
public class User extends ParseUser {
#Override
public String toString() {
Log.i("AppInfo", "Username: " + getUsername());
return getUsername();
}
}
}
Seems simple enough. I had this nested in my fragment class and it crashed with this
java.lang.ClassCastException: com.parse.ParseUser cannot be cast to com.mycompany.myproject.ExampleFragment$User
but when I move it into its own subclass (where it gets its own entry in the explorer view in android studio), it works perfectly.
Is there a reason it does not work nested in my fragment class? Seems a bit unnecessary to create its own subclass just to override one function.
UPDATE: If I remove the for loop part it does not error out, but it still does not call my overridden toString() as the listview returns com.parse.ParseUser#etcetcetc.
make sure you have do these 2 things
1.register class before Parse.initialize
ParseObject.registerSubclass(User.class);
2.use annotation to specified the class mapping to waht Class
#ParseClassName("_User")
public class User extends ParseUser {
...
}
here is the reference.
https://parse.com/docs/android/guide#objects-subclassing-parseobject
So I have this class here:
package phil.droid.game;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class GameList extends GamesTrialActivity
{
private ListView lv1;
protected String Game_names[]={"God of War","FOS RO DAH", "dhwaud"};
private String Game_pics[]={"God of War","God of War II"};
private int pos;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.gamelist);
lv1=(ListView)findViewById(R.id.thegamelist);
lv1.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1 , Game_names));
lv1.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
pos = position;
Intent i = new Intent(GameList.this, game_viewer.class);
startActivity(i);
}
});
}
}
And then this VclassV extends the one ^above^
package phil.droid.game;
import android.os.Bundle;
import android.widget.TextView;
public class game_viewer extends GameList
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.game_template);
TextView game_title = (TextView)findViewById(R.id.GameTitle);
game_title.setText("" + pos);
}
}
The problem is at the moment that the last bit recognizes "pos" as "0" no matter what option I click on. Can someone suggest a way to make it so pos is recognized as the number element that's clicked on in the previous class?
Make pos protected, not private.
What you're trying to do can't work: The newly launched activity will not share the same storage as the parent, even if they inherit. The only way it would be possible is if the value was static, but that's not a good idea either.
What you should do instead is to send the data as part of the intent before starting the activity, e.g.:
intent.putExtra("pos", position);
and then you can pull it out in the new activity with
getIntent().getIntExtra("pos", -1); // -1 is used as default value
Also, game_viewer should most likely be a separate activity, rather than inherit from GameList.