7

ネットから画像をダウンロードしてグリッドビューで表示する最初のアプリを開発しようとしています。グリッドビューはメイン アクティビティのフラグメントです。ダウンロード プロセスは、onCreate 関数の AsyncTask で行われます。向きを変えながら画像を再度ダウンロードしないようandroid:configChanges="orientation|screenSize"に、Android マニフェストに を設定しました。次に、onCreate関数は1回だけ呼び出され、すべてがうまくいきます...横向きモードのグリッドビューフラグメントのレイアウトにいくつかの変更を加える必要があることを除いて. だから私は2つのレイアウトシートを作成しました:fragment_library.xmlそしてfragment_library_land.xmllayout/ フォルダにあります。これらの変更を機能させるために、onConfigurationChanged 関数を使用して、ライブラリ フラグメントのレイアウトを手動で変更しようとしました。実行時に、プログラムは関数を評価し、適切なケース (ポートレートまたはランドスケープ) を渡しますが、使用されるレイアウトは依然としてポートレート モードのものです: fragment_library.xml...

public class LibraryFragment extends Fragment {
    public GridView gridview;
    private Boolean isImageAdapterPopulated = false;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        GetLibraryTask getLibraryTask = new GetLibraryTask(this);
        getLibraryTask.execute(Config.URL + "action=getLibrary");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        if (container == null)
            return null;

        // gridview
        View V = inflater.inflate(R.layout.fragment_library, container, false);
        gridview = (GridView)V.findViewById(R.id.gridview);

        if(this.isImageAdapterPopulated)
            this.setGridAdapter();
        return V;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
            inflater.inflate(R.layout.fragment_library_land, null);
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
            LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
            inflater.inflate(R.layout.fragment_library, null);
        }
    }

    public void setGridAdapter(){
        this.isImageAdapterPopulated = true;
        gridview.setAdapter(new ImageAdapter(getActivity()));
    }

    // ...
}

fragment_library.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="200dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="20dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
/>

fragment_library_land.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="400dp"
    android:numColumns="2"
    android:verticalSpacing="50dp"
    android:horizontalSpacing="50dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
/>

手伝ってくれてありがとう :)

4

2 に答える 2

16

それは不可能。フラグメントは、そのレイアウトを動的に更新できません。ただし、他にもいくつかのオプションがあります。

1 . これは好きではありませんが、縦向きと横向きの両方のビューを同時に表示し、表示と非表示を切り替える Fragment のレイアウトがあるかもしれません。

fragment_library.xml:

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview_portrait"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="200dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="20dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
/>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview_landscape"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="400dp"
    android:numColumns="2"
    android:verticalSpacing="50dp"
    android:horizontalSpacing="50dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
    android:visible="gone"
/>

次に、いくつかのプライベート メンバー変数:

private GridView mGridViewPortrait;
private GridView mGridViewLandscape;

次にonConfigurationChanged(Configuration newConfig)

@Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);

            if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                 mGridViewPortrait.setVisibility(View.VISIBLE);
                 mGridViewLandscape.setVisibility(View.GONE);
            }

            else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                 mGridViewPortrait.setVisibility(View.GONE);
                 mGridViewLandscape.setVisibility(View.VISIBLE);
            }
        }

いくつかのポイント: 両方の GridView を参照するコードを省略したことに注意してください。また、GridView をプライベートに変更し、名前を mGridView* に変更しました。クラスのメンバーであるため、「データカプセル化」および「m」を保持することはプライベートであり、単なる慣習です。肖像画のチェックを最初に行いたかったので、if-else 句も変更しました。

この方法が最も速くて簡単ですが、レイアウトが大きい場合はシステムが重くなる可能性があるため、多くの場合は使用しないでください。できれば、このアプローチをまったく使用しないでください。

2 . 適切な方法は、Andorid に向きを任せ、XML を正しいディレクトリに移動することです。ただし、これによりフラグメントが再作成されます(setRetainInstance(true);この場合は設定しない場合。これにより、フラグメントはレイアウトを再作成しなくなります(実際には、言及されていない保持メソッドonCreateViewを検索するため、これを true に設定することもできます)してみてください))。

fragment_library_land.xml を layout ではなく layout-land ディレクトリに移動し、fragment_library .xml という名前を付けます。太字に注意してください。名前は同じですが、別のディレクトリにとどまります。このようにして、Android は方向に基づいて正しいレイアウトを認識し、取得します。

onCreate(Bundle savedInstanceState)再び呼び出されるため、フラグメントを再作成したくない理由を理解した場合(setRetainInstance(true);そうではないので、以前に書いたことに関しては、試してみてください)、新しいインスタンスを作成してGetLibraryTask、画像を再度ダウンロードします. データベースを使用して画像を保存し、画像をダウンロードしたかどうかを追跡するブール値がある場合、これを防ぐことができます。次に、GetLibraryTaskタスクが初めて実行されるか、方向が変更された場合に、ダウンロードされていない画像を選択します。また、ダウンロード ループのライブラリ タスクに停止チェックを入れる必要があります。これは、各アイテムがイメージをダウンロードする必要があるかどうか、またはフラグメントが利用できなくなったためにタスクを終了するかどうかをチェックする前に行います。

向きを変更すると、アクティビティは LibraryFragment を再作成し、向きに応じてレイアウトまたはレイアウトランドが使用されます。

コード内の補足事項:

  • 前に書いたように、パブリック アクセスは絶対に使用せず、必要に応じて常にプライベートまたはプロテクトを使用してください。ただし、プライベートは常に使用でき、通信を行うためのゲッターとセッター (アクセサーとミューテーター) があります。
  • メンバー変数の接頭辞として「m」を使用します。この場合public GridView gridviewprivate GridView mGridViewprivate Boolean isImageAdapterPopulatedprivate boolean mIsImageAdapterPopulated
  • 必要がない場合は、プリミティブ型のクラスを使用しないでください。プリミティブ型やクラス保持などをサポートしていないリストで必要になる場合があります。
  • あなたonConfigurationChanged(Configuration newConfig)はXMLを膨らませ、それはビューを返しますが、あなたはそれで何もしていません

がんばって!

于 2013-01-29T09:58:06.663 に答える
0

oncongi change メソッドを使えば可能です。このリンクを参照してください向きの変更時にフラグメントのレイアウトを変更する

于 2014-03-14T10:36:35.473 に答える