简体   繁体   中英

How to solve listview with objects, single pane in portrait, dual pane in landscape

Im in a picle, currently trying to learn me some Android using The Big Nerd Ranch guide. But im having trouble understanding how i can get the app to rearrange the "detail view" from "new fragment" overlapping the listview to sidebyside view (listview left, details right).

Ive tried so many different guides and tutorials around the web now, but i guess im just to unstable in this to really figure it out. Cause all of them one way or another just ends up beeing nullpoint and so on. And im guessing that has something to do with the way the "book" builds it up vs the guides ive seen. So hopefully someone here can give me an hint.

The following code will display and listview, and when i click on an item it will replace the list fragment with another fragment displaying that item based on id from the click. Need it to display that information next to the listview when in landscape.

SignsMainActivity.class (first to be started with: Intent i = new Intent(getActivity(),SignsMainActivity.class); startActivity(i);)

public class SignsMainActivity extends SingleFragmentActivity {

@Override
protected Fragment createFragment() {
    return new SignsMainFragment();   }}

SignsMainFragment.class

public class SignsMainFragment extends ListFragment {

private ArrayList<Signs> storage;


@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    storage = SignStorage.get(getActivity()).getStorageOfSigns();
    SignAdapter adapter = new SignAdapter(storage);
    setListAdapter(adapter);
}

@Override
public void onResume() {
    super.onResume();
    ((SignAdapter)getListAdapter()).notifyDataSetChanged();
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    Signs signs = ((SignAdapter)getListAdapter()).getItem(position);

    Intent intent = new Intent(getActivity(), SignsActivity.class);
    intent.putExtra(SignsFragment.EXTRA_SIGNS_ID, signs.getId());
   startActivity(intent);}


private class SignAdapter extends ArrayAdapter<Signs> {

    public SignAdapter(ArrayList<Signs> sSigns){
        super(getActivity(), 0, sSigns);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        //If we were given a view, inflate one
        if(convertView ==null){
            convertView = getActivity().getLayoutInflater().inflate(R.layout.sign_row, null);
        }
        //Configure the view for this Crime
        Signs signs = getItem(position);
        TextView titleTextView = (TextView)convertView.findViewById(R.id.label);
        titleTextView.setText(signs.getName());

        return convertView;        }}}

SignsActivity.class

public class SignsActivity extends SingleFragmentActivity {

@Override
protected Fragment createFragment() {
    UUID signsId = (UUID) getIntent().getSerializableExtra(SignsFragment.EXTRA_SIGNS_ID);
    return SignsFragment.newInstance(signsId);}}

SignsFragment.class

public class SignsFragment extends Fragment{

public static final String EXTRA_SIGNS_ID = "signs_id";
private Signs mSign;
private TextView nameURLView;
private TextView imageURLView;
private TextView illustrationURLView;


@Override
public void onCreate(Bundle saveInstanceState){
    super.onCreate(saveInstanceState);
    UUID signsID = (UUID)getArguments().getSerializable(EXTRA_SIGNS_ID);
    mSign = SignStorage.get(getActivity()).getSign(signsID);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
    View view = inflater.inflate(R.layout.sign_details,parent,false);

    nameURLView = (TextView)view.findViewById(R.id.details);
    nameURLView.setText(mSign.getName());

    return view;
}

public static SignsFragment newInstance(UUID signsId){
    Bundle args = new Bundle();
    args.putSerializable(EXTRA_SIGNS_ID, signsId);

    SignsFragment fragment = new SignsFragment();
    fragment.setArguments(args);

    return fragment;
}}

SingleFragmentActivity.class (im guessing here is where i need to adjust the magic?)

public abstract class SingleFragmentActivity extends FragmentActivity {

//Used to instanciate the fragment (subclasses of this class will implement the method to return an instance of the fragment that the activity is hosting)
protected abstract Fragment createFragment();
private FragmentManager fm;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_single_fragment);

    fm = getSupportFragmentManager();
    Fragment fragment = fm.findFragmentById(R.id.singleFragmentContainer);

    if(fragment == null){
        fragment = createFragment();
        fm.beginTransaction().add(R.id.singleFragmentContainer, fragment).commit();
    }

}}

Storage of sign objects:

public class SignStorage {

private static SignStorage mSignStorage;
private Context context;
private ArrayList<Signs> storageOfSigns;
private Signs signs;
private static final String TAG="xx";

private SignStorage(Context appContext){
    context = appContext;
    storageOfSigns = new ArrayList<Signs>();
    primitiveFix();
}

public static SignStorage get(Context c){
    if (mSignStorage == null){
        mSignStorage = new SignStorage(c.getApplicationContext());
    }
    return mSignStorage;
}

public ArrayList<Signs> getStorageOfSigns() {
    return storageOfSigns;
}

public void setStorageOfSigns(ArrayList<Signs> storageOfSigns) {
    this.storageOfSigns = storageOfSigns;
}

public Signs getSign(UUID id){
    for (Signs s : storageOfSigns){
        if (s.getId().equals(id))
            return s;
    }
    return null;
}

private void primitiveFix(){

    String basePath = Environment.getExternalStorageDirectory().toString()+"/PictureTalk/Signs/";
    String name;
    String imageURL;
    String videoUrl;
    String illuUrl;
    Signs s;

    name = "abonnere";
    imageURL = basePath+"picture/adresse.jpg";
    videoUrl = basePath+"video/adresse.mp4";
    illuUrl = basePath+"illustrative/adresse.jpg";
    s = new Signs(name,imageURL,videoUrl,illuUrl);
    storageOfSigns.add(s);
THIS LIST GOES ON DOWNWARDS to get some items to display, will be filled later in another    
way...

Signs.class

public class Signs {

UUID id;
String name;
String videoURL;
String imageURL;
String illustrativeURL;

public Signs(String name,String videoURL,String imageURL,String illustrativeURL){
    this.id = UUID.randomUUID();
    this.name = name;
    this.videoURL = videoURL;
    this.imageURL = imageURL;
    this.illustrativeURL = illustrativeURL;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getVideoURL() {
    return videoURL;
}

public void setVideoURL(String videoURL) {
    this.videoURL = videoURL;
}

public String getBitmapURL() {
    return imageURL;
}

public void setBitmapURL(String bitmapURL) {
    this.imageURL = bitmapURL;
}

public UUID getId() {
    return id;
}

}

acitivty_single_fragment.xml (first blank xml)

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/singleFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>

sign_row.xml (xml for the listview)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
    android:id="@+id/label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@+id/label"
    android:textSize="20px" >
</TextView>

</LinearLayout> 

sign_details.xml (detail area for the object to be displayed, havent added more then textbox jet...)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
    android:id="@+id/details"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@+id/label"
    android:textSize="20px" >
</TextView>

</LinearLayout>

To implement a list / detail screen using fragments, you want to have a single activity that contains two fragments, not two separate activities. Generally, you can think of an activity as representing a full screen.

In other words, you don't need SingleFragmentActivity or SignsActivity. Your SignsMainActivity layout XML can then have your list and details fragment side-by-side. The fragments guide has a good example of the XML: http://developer.android.com/guide/components/fragments.html

Copying that XML and changing the names gives you a new signs_main_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="SignsMainFragment"
            android:id="@+id/signs-main"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="SignsFragment"
            android:id="@+id/signs"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

Then set this XML as your main activity's content view:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.signs_main_activity);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM