Various activities use same views from one layout - how to refactor? - android

I have six activities like this. I tried to make custom activity that hold ImageViews so I won't have to repeat myself in every activity. Should I leave it as it is or can I make it somehow be in one place and let it be used by everyone (like layout is - it's just one and works):
public class ActivityOne extends AppCompatActivity implements View.OnClickListener {
#Bind(R.id.iv1) ImageView iv1;
#Bind(R.id.iv2) ImageView iv2;
#Bind(R.id.iv3) ImageView iv3;
#Bind(R.id.iv4) ImageView iv4;
#Bind(R.id.iv5) ImageView iv5;
#Bind(R.id.iv6) ImageView iv6;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
iv1.setImageDrawable(getResources().getDrawable(R.drawable.c1));
iv2.setImageDrawable(getResources().getDrawable(R.drawable.c2));
iv3.setImageDrawable(getResources().getDrawable(R.drawable.c3));
iv4.setImageDrawable(getResources().getDrawable(R.drawable.c4));
iv5.setImageDrawable(getResources().getDrawable(R.drawable.c5));
iv6.setImageDrawable(getResources().getDrawable(R.drawable.c6));
}

You can create an abstract activity ImageryActivty that needs to override some method like getContentView which provides a layout id:
public abstract class ImageryActivity extends AppCompatActivity {
#Bind(R.id.iv1) ImageView iv1;
#Bind(R.id.iv2) ImageView iv2;
#Bind(R.id.iv3) ImageView iv3;
#Bind(R.id.iv4) ImageView iv4;
#Bind(R.id.iv5) ImageView iv5;
#Bind(R.id.iv6) ImageView iv6;
public abstract int getContentView();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentView());
ButterKnife.bind(this);
iv1.setImageDrawable(getResources().getDrawable(R.drawable.c1));
iv2.setImageDrawable(getResources().getDrawable(R.drawable.c2));
iv3.setImageDrawable(getResources().getDrawable(R.drawable.c3));
iv4.setImageDrawable(getResources().getDrawable(R.drawable.c4));
iv5.setImageDrawable(getResources().getDrawable(R.drawable.c5));
iv6.setImageDrawable(getResources().getDrawable(R.drawable.c6));
}
}
And your child activities must inherit from this one:
public class ActivityOne extends ImageryActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public int getContentView() {
return R.layout.activity_one;
}
}
Of course this layout must contain all the ImageView's with the proper id's. For this I´d recommend you to create a reusable layout imagery_layout and include it in each of your child activities:
<?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">
<include
layout="#layout/imagery_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!-- And here it comes the content for this particular activity in case there's one -->
</LinearLayout>

You can create one abstract BaseActivity activity that will have all the functionality common to those activities and then you can just extend the other activities with it that needs to have that common functionality
or you can simply use one activity and maintained all the states in it using some sort of switch statements all depends on your requirement

You should be able to do this with one Activity. You can pass arguments to Activities as Intent extras. Define some String constants in the Activity:
public static final String ARG_IN_IMAGE_ONE = "ActivityOne.ImageOne";
public static final String ARG_IN_IMAGE_TWO = "ActivityOne.ImageTwo";
...
Set your Drawable ids on creating the Intent:
intent.putIntExtra(ARG_IN_IMAGE_ONE, R.drawable.c1);
...
And read from the intent in onCreate:
iv1.setImageDrawable(getResources().getDrawable(getIntent().getIntExtra(ARG_IN_IMAGE_ONE)));
...
You can also optionally make a static builder which takes the 6 image ids and returns the Intent.

Related

ImageView not changing with setImageResource()?

Here's the code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
ImageView button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (ImageView)findViewById(R.id.startButton);
button.setOnClickListener(this);
button.setImageResource(R.drawable.play);
}
public void onClick(View v) {
button.setImageResource(R.drawable.pause);
}
}
Apparently if I put the button.setImageResource(R.drawable.pause);in the onCreate it works and changes images but not in the onClick? I tried debugging it and it ran the onClick code but didn't change the button image. I'm probably making a very stupid mistake but I can't figure it out.
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.larry.app.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/startButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true" />
</LinearLayout>
Make sure you use
android:src
to set the initial image in the xml.
you had better set ImageView self OnClickListener
Could you try this code and tell me the result then :
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
ImageView button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (ImageView)findViewById(R.id.startButton);
button.setOnClickListener(this);
button.setImageResource(R.drawable.play);
}
public void onClick(View v) {
button.setImageResource(R.drawable.pause);
}
}
and in the xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.larry.app.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/startButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true" />
</LinearLayout>
In the OnClick there is a switch statement, and when I put the button.setImageResource(R.drawable.pause); before the switch it doesn't always activate even when OnClick activates. When I click one button android.os.SystemClock.sleep is executed which prevents the image from swapping. When the other button is pressed the clock doesn't sleep, so the image can switch successfully.
I stumbled into the same problem Larry faced when using the setImageResource method when changing the source of an imageView. For me this happened when trying to use a switch but for a different scenario. Incase someone would find it helpful, i'll explain how I used a work around for this from the code.
SCENARIO
For me, I had a recyclerView in one activity and based on the selection, it would start another activity using an intent and the widgets in the new activity will be manipulated by the click of the recycler view including an imageView
SOLUTION
Using an If or a Switch inside the new class did not work (Which was the problem). What I did was inside the Custom Adapter for my recycler view, I used an If condition (Again a Switch will not work) as follows,
THE CLASS OF THE ACTIVITY WITH THE RECYCLER VIEW
`#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position)
{
holder.indexTextView.setText(String.valueOf(position + 1));
holder.nameTextView.setText(String.valueOf(name.get(position)));
holder.gradeTextView.setText(String.valueOf(grade.get(position)));
holder.itemView.setOnClickListener(v ->
{
Intent i = new Intent(context, DisplayingProductDetails.class);
if(novaGroup.get(position).equals(1))
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_1);
else if(novaGroup.get(position).equals(2))
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_2);
else if(novaGroup.get(position).equals(3))
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_3);
else if(novaGroup.get(position).equals(4))
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_4);
activity.startActivityForResult(i, 1);
});
}`
The Important Part here is passing the Resource ID as a String from the putExtra method.
if(novaGroup.get(position).equals(1))
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_1);
else if(novaGroup.get(position).equals(2))
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_2);
else if(novaGroup.get(position).equals(3))
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_3);
else
i.putExtra("PRODUCT_NOVA_GROUP", R.drawable.nova_grade_4);
FROM THE CLASS OF THE NEW ACTIVITY
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_displaying_product_details);
Bundle extras = getIntent().getExtras();
novaGroupImage = findViewById(R.id.novaGroupImage);
novaGroup = extras.getInt("PRODUCT_NOVA_GROUP");
novaGroupImage.setImageResource(novaGroup);
}
The important part here being using the resource ID inside the onCreate Method,
Bundle extras = getIntent().getExtras();
novaGroupImage = findViewById(R.id.novaGroupImage);

I have few imageview in activity_A and when i click a image in activity_A it should be opend in activity_B how?

Sir/Madam/Friends,
I am new to android program, I created one Linear layout in this activity I put 20 images, and when i click one image that particular image will open in another activity,in second activity i put only one Image view. So please how to do that?.
i did but my programe will showing only one same image only every time.
//this is the first activity.
public class abcd extends ActionBarActivity{
public final static String VIEW_ID = "name";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.abcd);
}
public void click(View view)
{
String iname=getResources().getResourceEntryName(view.getId());
Intent intent=new Intent(this,abcd_disp.class);
intent.putExtra("VIEW_ID", x);
startActivity(intent);
}
}
//this is the second activity
public class abcd_disp extends ActionBarActivity {
ImageView imageView;
int[] im=new int[]{
R.mipmap.a,R.mipmap.b
};
#Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent=getIntent();
String vidname=(String)intent.getStringExtra(abcd.VIEW_ID);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_abcd_disp);
if(vidname=="aa"){
imageView=(ImageView)findViewById(R.id.img_abcd_disp);
imageView.setImageResource(im[0]);
}
else
{
imageView=(ImageView)findViewById(R.id.img_abcd_disp);
imageView.setImageResource(im[1]);
}
}
The easiest way to do this is:
Suppose you have a set of images in drawable folder with which you are populating ImageView's in your Activity A .
Let the images be #drawable/image1, #drawable/image2, #drawable/image3, #drawable/image4
So once you click on the particular ImageView, you can retrieve image resource name as
imageView.getTag();
But this returns an object. So type cast it to String. This is done to pass it along with intent, since object cannot be passed directly without serializing or parceble.
String imageResourceName = (String)imageView.getTag();
Once you have this, pass this along with the Intent you are going to startActivity() with.
intent.putExtra("resource_name", imageResourceName);
startActivity(intent);
So in Activity B, where there is a ImageView, you set the image src in ImageView using
imageView.setTag(getIntent().getStringExtra("resource_name"));
Further information of setting image using setTag()
Use Fragment instead of the Activity!

android setting textview from another class with Fragments

I'm trying to set a textview text from another class
the textview is in the main activity and i need to set it from another class thats not an activity
In the past I have used the following
public class DemoActivity extends Activity {
public static TextView textViewObj1;
public static TextView textViewObj2;
public static TextView textViewObj3;
public static TextView textViewObj4;
public static TextView textViewObj5;
public void onCreate(final Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textViewObj1 = (TextView) findViewById(R.id.Sitename);
textViewObj2 = (TextView) findViewById(R.id.Building);
textViewObj3 = (TextView) findViewById(R.id.Floor);
textViewObj4 = (TextView) findViewById(R.id.Roomno);
textViewObj5 = (TextView) findViewById(R.id.Drawref);
I then set it in the other class by using
DemoActivity.textViewObj1.setText(c.getString(1));
DemoActivity.textViewObj2.setText(c.getString(2));
DemoActivity.textViewObj3.setText(c.getString(3));
DemoActivity.textViewObj4.setText(c.getString(4));
DemoActivity.textViewObj5.setText(c.getString(5));
The problem I have is the app im trying to set it for uses fragments and so the main activity instead of starting like this
public class DemoActivity extends Activity {
Starts like this
public class DemoActivity extends FragmentActivity {
for some reason when I try to set the textview from the other class using
DemoActivity.textViewObj5.setText(c.getString(5));
It gives the error : DemoActivity cannot be resolved
Any Ideas?
Your help is as always appreciated
Mark
Best practice is:
1) Define a listener interface in your fragment
public interface FragmentInteractionListener{
void onFragmentInteraction(String textToPut);
}
2) Implement this interface in your parentActivity:
public class MyParentActivity extends Activity implements FragmentInteractionListener {
...
#Override
public void onFragmentInteraction(String textToPut) {
//Update the textView here
}
3) In your fragment, call the parent Activity method:
((FragmentInteractionListener )getActivity()).onFragmentInteraction("This is the new text");
You may want to check if the parent activity is implementing the required interface in fragment's onAttach() method
Try Using DemoActivity.getActivity() or this.getActivity(). I know that when using an activity, we just call the context, but using fragments involves using getActivity.Hope this helps

android image display as per user choice on activity

I am new to android and would like to know as to why thiswont work.If i have a set of images in my res folder and i want to display them based on users choice such that the Mainactivity is like below:-
public class Activity3 extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.drawable.img1);//here i put the image name
}
}
Suppose i use this code snippet
public class Activity3 extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(R.id.text1=='1')
setContentView(R.drawable.img1);
else
setContentView(R.drawable.img2);
}
}
This doesnt work.But i would like to know why,how is the android stuff really working.This does seem to me logically right.
You can't set drawable to setContentView, but you can do this instead:
setContentView(R.layout.MyLayout);
ImageView view = (ImageView)findViewById(R.id.myviewid);
view.setImageResource(R.drawable.img1);
In each click add view.setImageResource(R.drawable.img1); to change the imageView resources.
if you see more carefully the documentation, can see the definition for setContentView method:
public void setContentView (int layoutResID)
if you note, the method receive a layoutResId, the key word is layout, remember that android used the logic (view - controller), an activity is the controller and a layout is the view. You can have visual elements in your view, like an image (in android can be contained in an ImageView).
For example, you can define an xml layout to the next way:
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/selected_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</ImageView>
this xml only contain an ImageView, in this ImageView with the id selected_image you will show the choice image.
In your activity you need put the next code (imagine the xml layout call image_layout.xml):
public class Activity3 extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_layout);
//here you need find the ImageView in this layout
((ImageView) findViewById(R.id.selected_image).setImageResource(R.drawable.img1);
}
}

Use single xml layout for multiple activities with different datas

I know this is a very basic question, however as a newbie i cant get to work around it.
So, I want to have multiple activities to use same the xml layout(consist for example of 1 imagebutton, and multiple textviews with different IDs). Now, for every activity, I want them to view the same layout but override the views with data unique to every activity. What is the best way to do this? And also, the imagebutton should open different URLs in a video player(youtube links).
And can somebody tell me what is the most practical way to learn android programming?
UPDATE
This is my current code:
public class TemakiActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contentviewer);
}
}
For example I have a textview with ID "descriptionviewer", and a button with ID "videolink", now, how do you code those in?
You can share the same layout file and the set the attributes for views in the onCreate(..) method of each activity.
If you want a different URL to open for each image button you could set it at runtime as follows
public void onCreate(Bundle b) {
Button button =(Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
//different action for each activity
}
});
}
Yes you can! I had multiple activities inflate the same layout but they save different shared preferences.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.same_layout);
TextView urlDesc = (TextView)findViewById(R.id.descriptionviewer);
urlDesc.setText("url_1"); //now in other activities-- urlDesc.setText("url_2");
ImageButton aButton = (ImageButton)findViewById(R.id.videolink);
aButton.setOnClickListener(aButtonListener);
}
private OnClickListener aButtonListener = new OnClickListener() {
public void onClick(View v) {
// go open url_1 here. In other activities, open url_x, url_y, url_z
finish();
}
};
Same code just swapping the text you want to set for the TextView and url to open in OnClickListener(). No more to change.

Categories

Resources